[asterisk-commits] mmichelson: branch group/CCSS r234376 - in /team/group/CCSS: apps/ channels/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 11 15:48:51 CST 2009


Author: mmichelson
Date: Fri Dec 11 15:48:46 2009
New Revision: 234376

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=234376
Log:
Add a new channel tech callback to call a callback for CC purposes.

When attempting to request an analog channel, or perhaps when trying
to request an ISDN channel when no B channels are available, ast_request
will fail to return a channel to the requester. The result of this is
that

1) We can't figure out the CC configuration parameters for the channel that
would have been returned.
2) We can't read a CC control frame.

In order to alleviate the problem, a new channel tech function has been created,
cc_callback. What this does is it allows us to dive into the channel driver, and
find out the interface that would have been found had ast_request not failed in
the first place. Once we find such an interface, we can call a supplied callback
so that the CC core can do whatever processing it may want or need to do.

It's a bit convoluted. Unfortunately, chan_dahdi just doesn't behave the same
way as most other channel drivers, and so special considerations have to be made.

Right now, the code in here does not compile because the chan_dahdi CC configuration
parsing is not implemented. That's up next, and then will come the fun part where
we attempt to figure out how to handle the situation in the CC core.


Modified:
    team/group/CCSS/apps/app_dial.c
    team/group/CCSS/channels/chan_dahdi.c
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/include/asterisk/channel.h
    team/group/CCSS/main/ccss.c
    team/group/CCSS/main/channel.c

Modified: team/group/CCSS/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/apps/app_dial.c?view=diff&rev=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/apps/app_dial.c (original)
+++ team/group/CCSS/apps/app_dial.c Fri Dec 11 15:48:46 2009
@@ -1891,6 +1891,7 @@
 			if (!rest) /* we are on the last destination */
 				chan->hangupcause = cause;
 			chanlist_free(tmp);
+			ast_cc_callback(tech, numsubst, ast_cc_busy_interface);
 			continue;
 		}
 		pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);

Modified: team/group/CCSS/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_dahdi.c?view=diff&rev=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/channels/chan_dahdi.c (original)
+++ team/group/CCSS/channels/chan_dahdi.c Fri Dec 11 15:48:46 2009
@@ -1427,6 +1427,7 @@
 static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
 static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
 static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
+static int dahdi_cc_callback(const char *dest, void (*callback)(struct ast_cc_config_params *cc_params, const char * const interface_name));
 
 static const struct ast_channel_tech dahdi_tech = {
 	.type = "DAHDI",
@@ -1449,6 +1450,7 @@
 	.queryoption = dahdi_queryoption,
 	.func_channel_read = dahdi_func_read,
 	.func_channel_write = dahdi_func_write,
+	.cc_callback = dahdi_cc_callback,
 };
 
 #define GET_CHANNEL(p) ((p)->channel)
@@ -12229,6 +12231,36 @@
 	}
 
 	return tmp;
+}
+
+static int dahdi_cc_callback(const char *dest, void (*callback)(struct ast_cc_config_params *cc_params, const char * const interface_name))
+{
+	struct dahdi_pvt *p, *exitpvt;
+	ast_group_t groupmatch = 0;
+	int groupmatched = 0;
+	int channelmatch = -1;
+	int channelmatched = 0;
+	int backwards = 0;
+	int roundrobin = 0;
+	/* STUB */
+	p = determine_starting_point((char *)dest, &groupmatch, &channelmatch, &backwards, &roundrobin);
+	exitpvt = p;
+	for(;;) {
+		if (is_group_or_channel_match(p, groupmatch, &groupmatched, channelmatch, &channelmatched)) {
+			/* We found a potential match. call the callback */
+			char interface_name[128];
+			snprintf(interface_name, sizeof(interface_name) - 1, "DAHDI/%s", dest);
+			callback(p->cc_params, interface_name);
+		}
+		p = backwards ? p->prev : p->next;
+		if (!p) {
+			p = backwards ? ifend : iflist;
+		}
+		if (p == exitpvt) {
+			break;
+		}
+	}
+	return 0;
 }
 
 #if defined(HAVE_SS7)

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=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Fri Dec 11 15:48:46 2009
@@ -1123,6 +1123,8 @@
  */
 int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char * const extension);
 
+void ast_cc_busy_interface(struct ast_cc_config_params *cc_params, const char * const interface_name);
+
 /*!
  * \since 1.6.4
  * \brief Initialize CCSS

Modified: team/group/CCSS/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/channel.h?view=diff&rev=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/include/asterisk/channel.h (original)
+++ team/group/CCSS/include/asterisk/channel.h Fri Dec 11 15:48:46 2009
@@ -515,6 +515,28 @@
 
 	/*! \brief Get the unique identifier for the PVT, i.e. SIP call-ID for SIP */
 	const char * (* get_pvt_uniqueid)(struct ast_channel *chan);
+
+	/*! \brief Call a function with cc parameters as a function parameter
+	 *
+	 * This is a highly specialized callback that is not likely to be needed in many
+	 * channel drivers. When dealing with a busy channel, for instance, most channel
+	 * drivers will successfully return a channel to the requester. Once called, the channel
+	 * can then queue a busy frame when it receives an appropriate message from the far end. 
+	 * In such a case, the channel driver has the opportunity to also queue a CC frame.
+	 * The parameters for the CC channel can be retrieved from the channel structure.
+	 *
+	 * For other channel drivers, notably those that deal with "dumb" phones, the channel
+	 * driver will not return a channel when one is requested. In such a scenario, there is never
+	 * an opportunity for the channel driver to queue a CC frame since the channel is never
+	 * called. Furthermore, it is not possible to retrieve the CC configuration parameters
+	 * for the desired channel because no channel is ever allocated or returned to the 
+	 * requester. In such a case, call completion may still be a viable option. What we do is
+	 * pass the same string that the requester used originally to request the channel to the
+	 * channel driver. The channel driver can then find any potential channels/devices that
+	 * match the input and return call the designated callback with the device's call completion
+	 * parameters as a parameter.
+	 */
+	int (* cc_callback)(const char *dest, void (*callback_fn)(struct ast_cc_config_params *cc_params, const char * const interface_name));
 };
 
 struct ast_epoll_data;
@@ -2806,6 +2828,20 @@
  */
 int ast_channel_get_device_name(struct ast_channel *chan, char *device_name, size_t name_buffer_length);
 
+/*!
+ * \since 1.6.4
+ * \brief Run a callback for potential matching destinations.
+ *
+ * See the explanation in ast_channel_tech::cc_callback for more
+ * details.
+ *
+ * \param tech Channel technology to use
+ * \param dest Channel/group/peer or whatever the specific technology uses
+ * \param callback Function to call when a target is reached
+ * \retval Always 0, I guess.
+ */
+int ast_cc_callback(const char * const tech, const char * const dest, void (*callback)(struct ast_cc_config_params *cc_params, const char * const interace_name));
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Fri Dec 11 15:48:46 2009
@@ -3168,6 +3168,12 @@
 	return ast_queue_frame(chan, &frame);
 }
 
+void ast_cc_busy_interface(struct ast_cc_config_params *cc_params, const char * const interface_name)
+{
+	/* STUB */
+	ast_log(LOG_NOTICE, "Called with interface %s\n", interface_name);
+}
+
 static char *ccreq_app = "CallCompletionRequest";
 
 static int ccreq_exec(struct ast_channel *chan, const char *data)

Modified: team/group/CCSS/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/channel.c?view=diff&rev=234376&r1=234375&r2=234376
==============================================================================
--- team/group/CCSS/main/channel.c (original)
+++ team/group/CCSS/main/channel.c Fri Dec 11 15:48:46 2009
@@ -7511,6 +7511,20 @@
 	return 0;
 }
 
+int ast_cc_callback(const char * const tech, const char * const dest, void (*callback)(struct ast_cc_config_params *cc_params, const char * const interface_name))
+{
+	struct chanlist *cl;
+
+	AST_RWLIST_RDLOCK(&backends);
+	AST_RWLIST_TRAVERSE(&backends, cl, list) {
+		if (!strcasecmp(cl->tech->type, tech) && cl->tech->cc_callback) {
+			cl->tech->cc_callback(dest, callback);
+		}
+	}
+	AST_RWLIST_UNLOCK(&backends);
+	return 0;
+}
+
 /* DO NOT PUT ADDITIONAL FUNCTIONS BELOW THIS BOUNDARY
  *
  * ONLY FUNCTIONS FOR PROVIDING BACKWARDS ABI COMPATIBILITY BELONG HERE




More information about the asterisk-commits mailing list