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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 18 14:26:20 CST 2010


Author: mmichelson
Date: Mon Jan 18 14:26:17 2010
New Revision: 241062

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=241062
Log:
Handle errors responses to CC PUBLISH requests.


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=241062&r1=241061&r2=241062
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Mon Jan 18 14:26:17 2010
@@ -1822,12 +1822,12 @@
 	return 0;
 }
 
-static void cc_handle_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry);
+static void cc_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry);
 
 static const struct epa_static_data cc_epa_static_data  = {
 	.event = CALL_COMPLETION,
 	.name = "call-completion",
-	.handle_error = cc_handle_error,
+	.handle_error = cc_handle_publish_error,
 };
 
 struct sip_epa_entry {
@@ -3661,6 +3661,12 @@
 {
 	struct sip_monitor_instance *monitor_instance = obj;
 	return monitor_instance->subscription_pvt == arg ? CMP_MATCH | CMP_STOP : 0;
+}
+
+static int find_sip_monitor_instance_by_suspension_entry(void *obj, void *arg, int flags)
+{
+	struct sip_monitor_instance *monitor_instance = obj;
+	return monitor_instance->suspension_entry == arg ? CMP_MATCH | CMP_STOP : 0;
 }
 
 static int sip_cc_monitor_init(struct ast_cc_monitor *monitor, const int core_id);
@@ -19726,24 +19732,54 @@
 	}
 }
 
-static void cc_handle_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
-{
-	/* XXX STUB
+static void cc_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
+{
+	struct cc_epa_entry *cc_entry = epa_entry->instance_data;
+	struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
+			find_sip_monitor_instance_by_suspension_entry, epa_entry);
+	const char *min_expires;
+
+	if (!monitor_instance) {
+		ast_log(LOG_WARNING, "Can't find monitor_instance corresponding to epa_entry %p.\n", epa_entry);
+		return;
+	}
+
+	if (resp != 423) {
+		ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->monitor->interface->name,
+				"Received error response to our PUBLISH");
+		ao2_ref(monitor_instance, -1);
+		return;
+	}
+
+	/* Allrighty, the other end doesn't like our Expires value. They think it's
+	 * too small, so let's see if they've provided a more sensible value. If they
+	 * haven't, then we'll just double our Expires value and see if they like that
+	 * instead.
 	 *
-	 * Here, things can be a bit interesting. Most error responses will result in our calling
-	 * ast_cc_monitor_failed, however, there are some exceptions.
-	 *
-	 * For instance, if we get a 423 Interval Too Brief response, we'll try sending another
-	 * PUBLISH with a larger Expires time. Of course, anyone who claims that 3600 seconds is
-	 * too brief is a jerk with no shoes.
-	 *
-	 * That's the only erroneous response I can think of that will not warrant a call to
-	 * ast_cc_monitor failed. Of course, 401 and 407 are both handled by the function that
-	 * calls this one, so we don't have to special case those.
-	 *
-	 * Once we've determined that we are going to call ast_cc_monitor_failed, we can get
-	 * the core ID of the CC transaction from the epa_entry->instance_data.
+	 * XXX Ideally this logic could be placed into its own function so that SUBSCRIBE,
+	 * PUBLISH, and REGISTER could all benefit from the same shared code.
 	 */
+	min_expires = get_header(req, "Min-Expires");
+	if (ast_strlen_zero(min_expires)) {
+		pvt->expiry *= 2;
+		if (pvt->expiry < 0) {
+			/* You dork! You overflowed! */
+			ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->monitor->interface->name,
+					"PUBLISH expiry overflowed");
+			ao2_ref(monitor_instance, -1);
+			return;
+		}
+	} else if (sscanf(min_expires, "%d", &pvt->expiry) != 1) {
+		ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->monitor->interface->name,
+				"Min-Expires has non-numeric value");
+		ao2_ref(monitor_instance, -1);
+		return;
+	}
+	/* At this point, we have most certainly changed pvt->expiry, so try transmitting
+	 * again
+	 */
+	transmit_invite(pvt, SIP_PUBLISH, FALSE, 0, NULL);
+	ao2_ref(monitor_instance, -1);
 }
 
 static void handle_response_publish(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)




More information about the asterisk-commits mailing list