[svn-commits] mmichelson: branch group/CCSS r234698 - in /team/group/CCSS: include/asterisk...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Dec 14 15:07:00 CST 2009


Author: mmichelson
Date: Mon Dec 14 15:06:58 2009
New Revision: 234698

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=234698
Log:
Add some helpful routines to CCSS code to build frames and their payloads.

The public ast_cc_build_frame will be used in chan_dahdi shortly. For now
it's used internally and has been tested to work as expected. Cool.


Modified:
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=234698&r1=234697&r2=234698
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Mon Dec 14 15:06:58 2009
@@ -1146,6 +1146,25 @@
 
 /*!
  * \since 1.6.4
+ * \brief Create a CC Control frame
+ *
+ * chan_dahdi is weird. It doesn't seem to actually queue frames when it needs to tell
+ * an application something. Instead it wakes up, tells the application that it has data
+ * ready, and then based on set flags, creates the proper frame type. For chan_dahdi, we
+ * provide this function. It provides us the data we need, and we'll make its frame for it.
+ *
+ * \param chan A channel involved in the call. What we want is on a datastore on both incoming and outgoing so either may be provided
+ * \param cc_params The CC configuration parameters for the outbound target
+ * \param interface_name The name of the outbound target
+ * \param[out] frame. The frame we will be returning to the caller. It is vital that ast_frame_free be called on this frame since the
+ * payload will be allocated on the heap.
+ * \retval -1 Failure. At some point there was a failure. Do not attempt to use the frame in this case.
+ * \retval 0 Success
+ */
+int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char * const interface_name, struct ast_frame *frame);
+
+/*!
+ * \since 1.6.4
  * \brief Initialize CCSS
  *
  * XXX This needs to be updated as more functionality is added.

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=234698&r1=234697&r2=234698
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Mon Dec 14 15:06:58 2009
@@ -3134,80 +3134,94 @@
 			cc_ref(core_instance, "Ref core instance for status response callback"));
 }
 
-int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type, enum ast_cc_service_type service)
-{
-	struct ast_frame frame = {.frametype = AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_CC };
-	struct ast_control_cc_payload payload;
-	struct ast_datastore *datastore;
-	struct dialed_cc_interfaces *dialed_interfaces;
-	char chan_name[AST_CHANNEL_NAME];
-
-	ast_channel_get_device_name(chan, chan_name, sizeof(chan_name));
-
-	if (ast_cc_monitor_count(chan_name, monitor_type) >= ast_get_cc_max_monitors(ast_channel_get_cc_config_params(chan))) {
-		ast_log(LOG_NOTICE, "Not queuing a CC frame for channel %s since it already has its maximum monitors allocated\n", chan_name);
-		return -1;
-	}
-
-	if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
-		/* If the channel doesn't have the proper datastore on it, we can't properly queue a
-		 * frame. Sorry bud.
-		 */
-		return -1;
-	}
-
-	dialed_interfaces = datastore->data;
-
-	payload.monitor_type = monitor_type;
-	payload.service = service;
-	payload.parent_interface_id = dialed_interfaces->dial_parent_id;
-	ast_copy_string(payload.device_name, chan_name, sizeof(payload.device_name));
-	ast_cc_copy_config_params(&payload.config_params, ast_channel_get_cc_config_params(chan));
-	frame.data.ptr = &payload;
-	frame.datalen = sizeof(payload);
-	return ast_queue_frame(chan, &frame);
-}
-
-/* XXX This function works under the assumption that it will only be called for a single interface name.
- */
-void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char * const interface_name)
-{
-	struct ast_control_cc_payload payload;
+static int cc_build_payload(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char * const interface_name, struct ast_control_cc_payload *payload)
+{
 	struct ast_datastore *datastore;
 	struct dialed_cc_interfaces *cc_interfaces;
 	enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(cc_params);
 	const char *interface_name_copy = ast_strdupa(interface_name);
-
-	if (!(datastore = ast_channel_datastore_find(inbound, &dialed_cc_interfaces_info, NULL))) {
-		return;
+	int dial_parent_id;
+
+	ast_channel_lock(chan);
+	if (!(datastore = ast_channel_datastore_find(chan, &dialed_cc_interfaces_info, NULL))) {
+		ast_channel_unlock(chan);
+		return -1;
 	}
 
 	cc_interfaces = datastore->data;
-
-	payload.service = AST_CC_CCBS;
+	dial_parent_id = cc_interfaces->dial_parent_id;
+	ast_channel_unlock(chan);
+
+	payload->service = AST_CC_CCBS;
 	if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) {
-		payload.monitor_type = "generic";
+		payload->monitor_type = "generic";
 	} else if (monitor_policy == AST_CC_MONITOR_NATIVE) {
 		char *slash = strchr(interface_name_copy, '/');
 		const struct ast_cc_monitor_callbacks *callbacks;
 		if (!slash) {
 			ast_log_dynamic_level(cc_logger_level, "Unable to determine proper CC monitor type.\n");
-			return;
+			return -1;
 		}
 		*slash = '\0';
 		if (!(callbacks = find_monitor_callbacks(interface_name_copy))) {
 			ast_log_dynamic_level(cc_logger_level, "No monitor type corresponds to %s\n", interface_name_copy);
-			return;
+			return -1;
 		}
-		payload.monitor_type = callbacks->type;
+		payload->monitor_type = callbacks->type;
 	} else { /* AST_CC_MONITOR_NEVER */
 		ast_log_dynamic_level(cc_logger_level, "Interface %s does not allow CC\n", interface_name);
+		return -1;
+	}
+	ast_cc_copy_config_params(&payload->config_params, cc_params);
+	payload->parent_interface_id = dial_parent_id;
+	ast_copy_string(payload->device_name, interface_name, sizeof(payload->device_name));
+	return 0;
+}
+
+int ast_queue_cc_frame(struct ast_channel *chan, const char *monitor_type, enum ast_cc_service_type service)
+{
+	struct ast_frame frame;
+	char chan_name[AST_CHANNEL_NAME];
+
+	ast_channel_get_device_name(chan, chan_name, sizeof(chan_name));
+
+	if (ast_cc_monitor_count(chan_name, monitor_type) >= ast_get_cc_max_monitors(ast_channel_get_cc_config_params(chan))) {
+		ast_log(LOG_NOTICE, "Not queuing a CC frame for channel %s since it already has its maximum monitors allocated\n", chan_name);
+		return -1;
+	}
+
+	if (ast_cc_build_frame(chan, ast_channel_get_cc_config_params(chan), chan_name, &frame)) {
+		/* Frame building failed. We can't use this. */
+		return -1;
+	}
+	return ast_queue_frame(chan, &frame);
+}
+
+int ast_cc_build_frame(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char * const interface_name, struct ast_frame *frame)
+{
+	struct ast_control_cc_payload *payload = ast_calloc(1, sizeof(*payload));
+	if (cc_build_payload(chan, cc_params, interface_name, payload)) {
+		/* Something screwed up, we can't make a frame with this */
+		ast_free(payload);
+		return -1;
+	}
+	frame->frametype = AST_FRAME_CONTROL;
+	frame->subclass.integer = AST_CONTROL_CC;
+	frame->data.ptr = payload;
+	frame->datalen = sizeof(*payload);
+	frame->mallocd = AST_MALLOCD_DATA;
+	return 0;
+}
+
+/* XXX This function works under the assumption that it will only be called for a single interface name.
+ */
+void ast_cc_busy_interface(struct ast_channel *inbound, struct ast_cc_config_params *cc_params, const char * const interface_name)
+{
+	struct ast_control_cc_payload payload;
+	if (cc_build_payload(inbound, cc_params, interface_name, &payload)) {
+		/* Something screwed up. Don't try to handle this payload */
 		return;
 	}
-	ast_cc_copy_config_params(&payload.config_params, cc_params);
-	payload.parent_interface_id =  cc_interfaces->dial_parent_id;
-	ast_copy_string(payload.device_name, interface_name, sizeof(payload.device_name));
-	/* Now we can simulate a frame! I love it! */
 	ast_handle_cc_control_frame(inbound, NULL, &payload);
 }
 




More information about the svn-commits mailing list