[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