[asterisk-commits] mmichelson: branch group/CCSS r236710 - /team/group/CCSS/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Dec 28 13:12:57 CST 2009


Author: mmichelson
Date: Mon Dec 28 13:12:55 2009
New Revision: 236710

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=236710
Log:
Fill in sip_handle_cc a bit more.

Next step is to actually parse the bits out of the response.


Modified:
    team/group/CCSS/channels/chan_sip.c

Modified: team/group/CCSS/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_sip.c?view=diff&rev=236710&r1=236709&r2=236710
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Mon Dec 28 13:12:55 2009
@@ -3618,8 +3618,7 @@
 	ast_copy_string(monitor_instance->subscribe_uri, subscribe_uri, sizeof(monitor_instance->subscribe_uri));
 	monitor_instance->core_id = core_id;
 	ao2_link(sip_monitor_instances, monitor_instance);
-	/* Get rid of ref from allocation */
-	ao2_ref(monitor_instance, -1);
+	return monitor_instance;
 }
 
 static struct sip_monitor_instance *find_sip_monitor_instance(int core_id)
@@ -3783,14 +3782,72 @@
 	ao2_ref(monitor_instance, -1);
 }
 
-static void sip_handle_cc(struct sip_pvt *pvt, enum ast_cc_service_type service)
-{
-	if (ast_get_cc_monitor_policy(pvt->cc_params) == AST_CC_MONITOR_GENERIC) {
-		char interface_name[AST_CHANNEL_NAME];
-		ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name));
+static int sip_get_cc_information(struct sip_request *req, char *subsribe_uri, size_t size, enum ast_cc_service_type *service)
+{
+	/* STUB */
+	return 0;
+}
+
+/*
+ * \brief Determine what, if any, CC has been offered and queue a CC frame if possible
+ *
+ * After taking care of some formalities to be sure that this call is eligible for CC,
+ * we first try to see if we can make use of native CC. We grab the information from
+ * the passed-in sip_request (which is always a response to an INVITE). If we can
+ * use native CC monitoring for the call, then so be it.
+ *
+ * If native cc monitoring is not possible or not supported, then we will instead attempt
+ * to use generic monitoring. Falling back to generic from a failed attempt at using native
+ * monitoring will only work if the monitor policy of the endpoint is "always"
+ *
+ * \param pvt The current dialog. Contains CC parameters for the endpoint
+ * \param req The response to the INVITE we want to inspect
+ * \param service The service to use if generic monitoring is to be used. For native
+ * monitoring, we get the service from the SIP response itself
+ */
+static void sip_handle_cc(struct sip_pvt *pvt, struct sip_request *req, enum ast_cc_service_type service)
+{
+	enum ast_cc_monitor_policies monitor_policy = ast_get_cc_monitor_policy(pvt->cc_params);
+	int core_id;
+	char interface_name[AST_CHANNEL_NAME];
+
+	if (monitor_policy == AST_CC_MONITOR_NEVER) {
+		/* Don't bother, just return */
+		return;
+	}
+
+	if ((core_id = ast_cc_get_current_core_id(pvt->owner)) == -1) {
+		/* For some reason, CC is invalid, so don't try it! */
+		return;
+	}
+
+	ast_channel_get_device_name(pvt->owner, interface_name, sizeof(interface_name));
+
+	if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) {
+		char subscribe_uri[SIPBUFSIZE];
+		enum ast_cc_service_type offered_service;
+		struct sip_monitor_instance *monitor_instance;
+		if (sip_get_cc_information(req, subscribe_uri, sizeof(subscribe_uri), &offered_service)) {
+			/* If CC isn't being offered to us, or for some reason the CC offer is
+			 * not formatted correctly, then it may still be possible to use generic
+			 * call completion since the monitor policy may be "always"
+			 */
+			goto generic;
+		}
+		if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri))) {
+			/* Same deal. We can try using generic still */
+			goto generic;
+		}
+		/* We're all set! */
+		ast_queue_cc_frame(pvt->owner, interface_name, "SIP", offered_service);
+		ao2_ref(monitor_instance, -1);
+		return;
+	}
+
+generic:
+	if (monitor_policy == AST_CC_MONITOR_GENERIC || monitor_policy == AST_CC_MONITOR_ALWAYS) {
 		ast_queue_cc_frame(pvt->owner, interface_name, AST_CC_GENERIC_MONITOR_TYPE, service);
 	}
-	return;
 }
 
 /*! \brief Working TLS connection configuration */
@@ -19697,7 +19754,7 @@
 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 				ast_channel_queue_connected_line_update(p->owner, &connected);
 			}
-			sip_handle_cc(p, AST_CC_CCNR);
+			sip_handle_cc(p, req, AST_CC_CCNR);
 			ast_queue_control(p->owner, AST_CONTROL_RINGING);
 			if (p->owner->_state != AST_STATE_UP) {
 				ast_setstate(p->owner, AST_STATE_RINGING);
@@ -19722,7 +19779,7 @@
 			struct ast_party_redirecting redirecting = {{0,},};
 			change_redirecting_information(p, req, &redirecting, FALSE);
 			ast_channel_queue_redirecting_update(p->owner, &redirecting);
-			sip_handle_cc(p, AST_CC_CCNR);
+			sip_handle_cc(p, req, AST_CC_CCNR);
 		}
 		check_pendings(p);
 		break;
@@ -19740,7 +19797,7 @@
 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 				ast_channel_queue_connected_line_update(p->owner, &connected);
 			}
-			sip_handle_cc(p, AST_CC_CCNR);
+			sip_handle_cc(p, req, AST_CC_CCNR);
 		}
 		if (find_sdp(req)) {
 			if (p->invitestate != INV_CANCELLED)
@@ -20700,7 +20757,7 @@
 				case 600: /* Busy everywhere */
 				case 603: /* Decline */
 					if (p->owner) {
-						sip_handle_cc(p, AST_CC_CCBS);
+						sip_handle_cc(p, req, AST_CC_CCBS);
 						ast_queue_control(p->owner, AST_CONTROL_BUSY);
 					}
 					break;




More information about the asterisk-commits mailing list