[asterisk-commits] mmichelson: branch group/CCSS r234698 - in /team/group/CCSS: include/asterisk...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list