[svn-commits] mmichelson: branch group/CCSS r244557 - in /team/group/CCSS: channels/ includ...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Feb 3 14:15:06 CST 2010


Author: mmichelson
Date: Wed Feb  3 14:15:00 2010
New Revision: 244557

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=244557
Log:
Merge the CCSS_Monitor_Restructure branch.

Tests show things are still working as expected, and
so now the biggest things standing between what's here
now and what will be in trunk are some general cleanups,
such as consistency in names of variables in the API,
making sure doxygen is correct on all functions and that
doxygen exists on all functions, scanning for any
lingering XXX comments in CC code (I know of one in app_dial
that will be FUN to address), and any other finishing
touches that need to be made.


Removed:
    team/group/CCSS/tests/test_utils.c
Modified:
    team/group/CCSS/channels/chan_dahdi.c
    team/group/CCSS/channels/chan_sip.c
    team/group/CCSS/channels/sig_analog.c
    team/group/CCSS/channels/sig_pri.c
    team/group/CCSS/channels/sig_pri.h
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

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=244557&r1=244556&r2=244557
==============================================================================
--- team/group/CCSS/channels/chan_dahdi.c (original)
+++ team/group/CCSS/channels/chan_dahdi.c Wed Feb  3 14:15:00 2010
@@ -2864,6 +2864,30 @@
 	snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
 }
 
+/*!
+ * \internal
+ * \brief Reference this module.
+ * \since 1.8
+ *
+ * \return Nothing
+ */
+static void my_module_ref(void)
+{
+	ast_module_ref(ast_module_info->self);
+}
+
+/*!
+ * \internal
+ * \brief Unreference this module.
+ * \since 1.8
+ *
+ * \return Nothing
+ */
+static void my_module_unref(void)
+{
+	ast_module_unref(ast_module_info->self);
+}
+
 static int dahdi_new_pri_nobch_channel(struct sig_pri_pri *pri);
 
 static struct sig_pri_callback dahdi_pri_callbacks =
@@ -2884,6 +2908,8 @@
 	.new_nobch_intf = dahdi_new_pri_nobch_channel,
 	.get_orig_dialstring = my_get_orig_dialstring,
 	.make_cc_dialstring = my_pri_make_cc_dialstring,
+	.module_ref = my_module_ref,
+	.module_unref = my_module_unref,
 };
 #endif	/* defined(HAVE_PRI) */
 
@@ -12542,7 +12568,7 @@
 #else
 					p->cc_params,
 #endif	/* defined(HAVE_PRI) */
-					monitor_type, full_device_name, dialstring);
+					monitor_type, full_device_name, dialstring, NULL);
 				break;
 			}
 		}
@@ -15973,72 +15999,14 @@
 
 #if defined(HAVE_PRI)
 #if defined(HAVE_PRI_CCSS)
-/*!
- * \internal
- * \brief CC monitor initialization.
- * \since 1.8
- *
- * \param monitor CC core monitor control.
- * \param core_id core_id of the CC transaction.
- *
- * \details
- * Implementers must allocate the monitor's private_data
- * and initialize it to whatever may be necessary.
- *
- * \retval 0 on success
- * \retval -1 on failure.
- */
-static int dahdi_pri_cc_monitor_init(struct ast_cc_monitor *monitor, const int core_id)
-{
-	int res;
-
-	ast_module_ref(ast_module_info->self);
-
-	res = sig_pri_cc_monitor_init(monitor, core_id);
-	if (res) {
-		ast_module_unref(ast_module_info->self);
-	}
-	return res;
-}
-
-#endif	/* defined(HAVE_PRI_CCSS) */
-#endif	/* defined(HAVE_PRI) */
-
-#if defined(HAVE_PRI)
-#if defined(HAVE_PRI_CCSS)
-/*!
- * \internal
- * \brief Destroy private data on the monitor.
- * \since 1.8
- *
- * \param monitor CC core monitor control.
- *
- * \details
- * Implementers of this callback are responsible for destroying
- * all heap-allocated data in the monitor's private_data pointer, including
- * the private_data itself.
- */
-static void dahdi_pri_cc_monitor_destructor(struct ast_cc_monitor *monitor)
-{
-	sig_pri_cc_monitor_destructor(monitor);
-
-	ast_module_unref(ast_module_info->self);
-}
-#endif	/* defined(HAVE_PRI_CCSS) */
-#endif	/* defined(HAVE_PRI) */
-
-#if defined(HAVE_PRI)
-#if defined(HAVE_PRI_CCSS)
 static struct ast_cc_monitor_callbacks dahdi_pri_cc_monitor_callbacks = {
 	.type = dahdi_pri_cc_type,
-	.init = dahdi_pri_cc_monitor_init,
 	.request_cc = sig_pri_cc_monitor_req_cc,
 	.suspend = sig_pri_cc_monitor_suspend,
 	.unsuspend = sig_pri_cc_monitor_unsuspend,
 	.status_response = sig_pri_cc_monitor_status_rsp,
 	.cancel_available_timer = sig_pri_cc_monitor_cancel_available_timer,
-	.destructor = dahdi_pri_cc_monitor_destructor,
-	.instance_destructor = sig_pri_cc_monitor_instance_destructor,
+	.destructor = sig_pri_cc_monitor_destructor,
 };
 #endif	/* defined(HAVE_PRI_CCSS) */
 #endif	/* defined(HAVE_PRI) */

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=244557&r1=244556&r2=244557
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Wed Feb  3 14:15:00 2010
@@ -216,7 +216,18 @@
 
 #include "asterisk/network.h"
 #include "asterisk/paths.h"	/* need ast_config_AST_SYSTEM_NAME */
-
+/*
+   Uncomment the define below,  if you are having refcount related memory leaks.
+   With this uncommented, this module will generate a file, /tmp/refs, which contains
+   a history of the ao2_ref() calls. To be useful, all calls to ao2_* functions should
+   be modified to ao2_t_* calls, and include a tag describing what is happening with
+   enough detail, to make pairing up a reference count increment with its corresponding decrement.
+   The refcounter program in utils/ can be invaluable in highlighting objects that are not
+   balanced, along with the complete history for that object.
+   In normal operation, the macros defined will throw away the tags, so they do not
+   affect the speed of the program at all. They can be considered to be documentation.
+*/
+/* #define  REF_DEBUG 1 */
 #include "asterisk/lock.h"
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
@@ -241,18 +252,6 @@
 #include "asterisk/file.h"
 #include "asterisk/astobj.h"
 #include "asterisk/test.h"
-/*
-   Uncomment the define below,  if you are having refcount related memory leaks.
-   With this uncommented, this module will generate a file, /tmp/refs, which contains
-   a history of the ao2_ref() calls. To be useful, all calls to ao2_* functions should
-   be modified to ao2_t_* calls, and include a tag describing what is happening with
-   enough detail, to make pairing up a reference count increment with its corresponding decrement.
-   The refcounter program in utils/ can be invaluable in highlighting objects that are not
-   balanced, along with the complete history for that object.
-   In normal operation, the macros defined will throw away the tags, so they do not
-   affect the speed of the program at all. They can be considered to be documentation.
-*/
-/* #define  REF_DEBUG 1 */
 #include "asterisk/astobj2.h"
 #include "asterisk/dnsmgr.h"
 #include "asterisk/devicestate.h"
@@ -1805,6 +1804,7 @@
 	const char *name;
 	void (*handle_ok)(struct sip_pvt *, struct sip_request *, struct sip_epa_entry *);
 	void (*handle_error)(struct sip_pvt *, const int resp, struct sip_request *, struct sip_epa_entry *);
+	void (*destructor)(void *instance_data);
 };
 
 struct epa_backend {
@@ -1830,12 +1830,6 @@
 }
 
 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_publish_error,
-};
 
 struct sip_epa_entry {
 	/* When we are going to send a publish, we need to
@@ -1870,6 +1864,20 @@
 	void *instance_data;
 };
 
+static void cc_epa_destructor(void *data)
+{
+	struct sip_epa_entry *epa_entry = data;
+	struct cc_epa_entry *cc_entry = epa_entry->instance_data;
+	ast_free(cc_entry);
+}
+
+static const struct epa_static_data cc_epa_static_data  = {
+	.event = CALL_COMPLETION,
+	.name = "call-completion",
+	.handle_error = cc_handle_publish_error,
+	.destructor = cc_epa_destructor,
+};
+
 static const struct epa_static_data *find_static_data(const char * const event_package)
 {
 	const struct epa_backend *backend = NULL;
@@ -1889,12 +1897,11 @@
 	struct sip_epa_entry *epa_entry;
 	const struct epa_static_data *static_data;
 
-	if (!(epa_entry = ao2_alloc(sizeof(*epa_entry), NULL))) {
+	if (!(static_data = find_static_data(event_package))) {
 		return NULL;
 	}
 
-	if (!(static_data = find_static_data(event_package))) {
-		ao2_ref(epa_entry, -1);
+	if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) {
 		return NULL;
 	}
 
@@ -3596,8 +3603,8 @@
 		AST_STRING_FIELD(subscribe_uri);
 		AST_STRING_FIELD(notify_uri);
 		AST_STRING_FIELD(peername);
+		AST_STRING_FIELD(device_name);
 	);
-	struct ast_cc_monitor *monitor;
 	int core_id;
 	struct sip_pvt *subscription_pvt;
 	struct sip_epa_entry *suspension_entry;
@@ -3630,15 +3637,12 @@
 	if (monitor_instance->suspension_entry) {
 		monitor_instance->suspension_entry->body[0] = '\0';
 		transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_REMOVE ,monitor_instance->notify_uri);
-		ao2_ref(monitor_instance->suspension_entry, -1);
-	}
-	if (monitor_instance->monitor) {
-		ao2_ref(monitor_instance->monitor, -1);
+		ao2_t_ref(monitor_instance->suspension_entry, -1, "Decrementing suspension entry refcount in sip_monitor_instance_destructor");
 	}
 	ast_string_field_free_memory(monitor_instance);
 }
 
-static struct sip_monitor_instance *sip_monitor_instance_init(int core_id, const char * const subscribe_uri, const char * const peername)
+static struct sip_monitor_instance *sip_monitor_instance_init(int core_id, const char * const subscribe_uri, const char * const peername, const char * const device_name)
 {
 	struct sip_monitor_instance *monitor_instance = ao2_alloc(sizeof(*monitor_instance), sip_monitor_instance_destructor);
 
@@ -3653,17 +3657,12 @@
 
 	ast_string_field_set(monitor_instance, subscribe_uri, subscribe_uri);
 	ast_string_field_set(monitor_instance, peername, peername);
+	ast_string_field_set(monitor_instance, device_name, device_name);
 	monitor_instance->core_id = core_id;
 	ao2_link(sip_monitor_instances, monitor_instance);
 	return monitor_instance;
 }
 
-static struct sip_monitor_instance *find_sip_monitor_instance(int core_id)
-{
-	struct sip_monitor_instance finder = { .core_id = core_id };
-	return ao2_find(sip_monitor_instances, &finder, OBJ_POINTER);
-}
-
 static int find_sip_monitor_instance_by_subscription_pvt(void *obj, void *arg, int flags)
 {
 	struct sip_monitor_instance *monitor_instance = obj;
@@ -3676,37 +3675,27 @@
 	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);
-static int sip_cc_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
-static int sip_cc_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
-static int sip_cc_monitor_status_response(struct ast_cc_monitor *monitor, const int core_id, enum ast_device_state devstate);
-static int sip_cc_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id);
-static int sip_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, const int core_id, int *sched_id);
-static void sip_cc_monitor_destructor(struct ast_cc_monitor *monitor);
-static void sip_cc_monitor_instance_destructor(const int core_id);
+static int sip_cc_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id);
+static int sip_cc_monitor_suspend(struct ast_cc_monitor *monitor);
+static int sip_cc_monitor_status_response(struct ast_cc_monitor *monitor, enum ast_device_state devstate);
+static int sip_cc_monitor_unsuspend(struct ast_cc_monitor *monitor);
+static int sip_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id);
+static void sip_cc_monitor_destructor(void *private_data);
 
 static struct ast_cc_monitor_callbacks sip_cc_monitor_callbacks = {
 	.type = "SIP",
-	.init = sip_cc_monitor_init,
 	.request_cc = sip_cc_monitor_request_cc,
 	.suspend = sip_cc_monitor_suspend,
 	.status_response = sip_cc_monitor_status_response,
 	.unsuspend = sip_cc_monitor_unsuspend,
 	.cancel_available_timer = sip_cc_monitor_cancel_available_timer,
 	.destructor = sip_cc_monitor_destructor,
-	.instance_destructor = sip_cc_monitor_instance_destructor,
 };
 
-static int sip_cc_monitor_init(struct ast_cc_monitor *monitor, const int core_id)
-{
-	/* Nothing to do here */
-	return 0;
-}
-
-static int sip_cc_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link)
-{
-	struct sip_monitor_instance *monitor_instance = find_sip_monitor_instance(core_id);
-	enum ast_cc_service_type service = parent_link->service;
+static int sip_cc_monitor_request_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
+{
+	struct sip_monitor_instance *monitor_instance = monitor->private_data;
+	enum ast_cc_service_type service = monitor->service_offered;
 	int when;
 
 	if (!monitor_instance) {
@@ -3717,9 +3706,6 @@
 		return -1;
 	}
 
-	monitor_instance->monitor = monitor;
-	ao2_ref(monitor_instance->monitor, +1);
-	
 	when = service == AST_CC_CCBS ? ast_get_ccbs_available_timer(monitor->interface->config_params) :
 		ast_get_ccnr_available_timer(monitor->interface->config_params);
 
@@ -3732,8 +3718,8 @@
 	transmit_invite(monitor_instance->subscription_pvt, SIP_SUBSCRIBE, FALSE, 2, monitor_instance->subscribe_uri);
 	sip_pvt_unlock(monitor_instance->subscription_pvt);
 
-	parent_link->child_avail_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, parent_link);
-	ao2_ref(monitor_instance, -1);
+	ao2_t_ref(monitor, +1, "Adding a ref to the monitor for the scheduler");
+	*available_timer_id = ast_sched_add(sched, when * 1000, ast_cc_available_timer_expire, monitor);
 	return 0;
 }
 
@@ -3758,10 +3744,11 @@
 	return 0;
 }
 
-static int sip_cc_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id)
-{
-	struct sip_monitor_instance *monitor_instance = find_sip_monitor_instance(core_id);
+static int sip_cc_monitor_suspend(struct ast_cc_monitor *monitor)
+{
+	struct sip_monitor_instance *monitor_instance = monitor->private_data;
 	enum sip_publish_type publish_type;
+	struct cc_epa_entry *cc_entry;
 
 	if (!monitor_instance) {
 		return -1;
@@ -3774,19 +3761,41 @@
 			ao2_ref(monitor_instance, -1);
 			return -1;
 		}
+		if (!(cc_entry = ast_calloc(1, sizeof(*cc_entry)))) {
+			ast_log(LOG_WARNING, "Unable to allocate space for instance data of EPA entry for call-completion\n");
+			ao2_ref(monitor_instance, -1);
+			return -1;
+		}
+		cc_entry->core_id = monitor->core_id;
+		monitor_instance->suspension_entry->instance_data = cc_entry;
 		publish_type = SIP_PUBLISH_INITIAL;
 	} else {
 		publish_type = SIP_PUBLISH_MODIFY;
-	}
-
+		cc_entry = monitor_instance->suspension_entry->instance_data;
+	}
+
+	cc_entry->current_state = CC_CLOSED;
+
+	if (ast_strlen_zero(monitor_instance->notify_uri)) {
+		/* If we have no set notify_uri, then what this means is that we have
+		 * not received a NOTIFY from this destination stating that he is
+		 * currently available.
+		 *
+		 * This situation can arise when the core calls the suspend callbacks
+		 * of multiple destinations. If one of the other destinations aside
+		 * from this one notified Asterisk that he is available, then there
+		 * is no reason to take any suspension action on this device. Rather,
+		 * we should return now and if we receive a NOTIFY while monitoring
+		 * is still "suspended" then we can immediately respond with the
+		 * proper PUBLISH to let this endpoint know what is going on.
+		 */
+		return 0;
+	}
 	construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body));
-	transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri);
-
-	ao2_ref(monitor_instance, -1);
-	return 0;
-}
-
-static int sip_cc_monitor_status_response(struct ast_cc_monitor *monitor, const int core_id, enum ast_device_state devstate)
+	return transmit_publish(monitor_instance->suspension_entry, publish_type, monitor_instance->notify_uri);
+}
+
+static int sip_cc_monitor_status_response(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
 {
 	/* This will never be called because the SIP monitor will never make a status request to
 	 * begin with
@@ -3794,9 +3803,10 @@
 	return 0;
 }
 
-static int sip_cc_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id)
-{
-	struct sip_monitor_instance *monitor_instance = find_sip_monitor_instance(core_id);
+static int sip_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
+{
+	struct sip_monitor_instance *monitor_instance = monitor->private_data;
+	struct cc_epa_entry *cc_entry;
 
 	if (!monitor_instance) {
 		return -1;
@@ -3804,34 +3814,33 @@
 
 	ast_assert(monitor_instance->suspension_entry != NULL);
 
+	cc_entry = monitor_instance->suspension_entry->instance_data;
+	cc_entry->current_state = CC_OPEN;
+	if (ast_strlen_zero(monitor_instance->notify_uri)) {
+		/* This means we are being asked to unsuspend a call leg we never
+		 * sent a PUBLISH on. As such, there is no reason to send another
+		 * PUBLISH at this point either. We can just return instead.
+		 */
+		return 0;
+	}
 	construct_pidf_body(CC_OPEN, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body));
-	transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri);
-
-	ao2_ref(monitor_instance, -1);
-	return 0;
-}
-
-static int sip_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, const int core_id, int *sched_id)
+	return transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_MODIFY, monitor_instance->notify_uri);
+}
+
+static int sip_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
 {
 	if (*sched_id != -1) {
 		AST_SCHED_DEL(sched, *sched_id);
+		ao2_t_ref(monitor, -1, "Removing scheduler's reference to the monitor");
 	}
 	return 0;
 }
 
-static void sip_cc_monitor_destructor(struct ast_cc_monitor *monitor)
-{
-	/* Nothing to do here. */
-}
-
-static void sip_cc_monitor_instance_destructor(const int core_id)
-{
-	struct sip_monitor_instance *monitor_instance = find_sip_monitor_instance(core_id);
-	if (!monitor_instance) {
-		return;
-	}
+static void sip_cc_monitor_destructor(void *private_data)
+{
+	struct sip_monitor_instance *monitor_instance = private_data;
 	ao2_unlink(sip_monitor_instances, monitor_instance);
-	ao2_ref(monitor_instance, -1);
+	ast_module_unref(ast_module_info->self);
 }
 
 static int sip_get_cc_information(struct sip_request *req, char *subscribe_uri, size_t size, enum ast_cc_service_type *service)
@@ -3923,6 +3932,7 @@
 
 	if (monitor_policy == AST_CC_MONITOR_ALWAYS || monitor_policy == AST_CC_MONITOR_NATIVE) {
 		char subscribe_uri[SIPBUFSIZE];
+		char device_name[AST_CHANNEL_NAME];
 		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)) {
@@ -3932,19 +3942,24 @@
 			 */
 			goto generic;
 		}
-		if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername))) {
+		ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
+		if (!(monitor_instance = sip_monitor_instance_init(core_id, subscribe_uri, pvt->peername, device_name))) {
 			/* Same deal. We can try using generic still */
 			goto generic;
 		}
-		/* We're all set! */
-		ast_queue_cc_frame(pvt->owner, "SIP", interface_name, offered_service);
+		/* We bump the refcount of chan_sip because once we queue this frame, the CC core
+		 * will have a reference to callbacks in this module. We decrement the module
+		 * refcount once the monitor destructor is called
+		 */
+		ast_module_ref(ast_module_info->self);
+		ast_queue_cc_frame(pvt->owner, "SIP", interface_name, offered_service, monitor_instance);
 		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, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service);
+		ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE, interface_name, service, NULL);
 	}
 }
 
@@ -6810,7 +6825,6 @@
 	struct varshead *headp;
 	struct ast_var_t *current;
 	const char *referer = NULL;   /* SIP referrer */
-	struct sip_monitor_instance *monitor_instance = NULL;
 	int cc_core_id;
 	char uri[SIPBUFSIZE] = "";
 
@@ -6820,18 +6834,15 @@
 	}
 
 	if (ast_cc_is_recall(ast, &cc_core_id, "SIP")) {
-		/* If this is a CC recall, then we have a particular
-		 * URI that we are supposed to send the INVITE to. We
-		 * get this information from the corresponding sip_monitor_instance
-		 */
-		if (!(monitor_instance = find_sip_monitor_instance(cc_core_id))) {
-			/* UM... */
-			ast_log(LOG_WARNING, "This is a recall, but we can't find an appropriate sip_monitor_instance with core ID %d.\n", cc_core_id);
-			/* We'll still try to continue with things. They just may not work as planned... */
-		} else {
+		char device_name[AST_CHANNEL_NAME];
+		struct ast_cc_monitor *recall_monitor;
+		struct sip_monitor_instance *monitor_instance;
+		ast_channel_get_device_name(ast, device_name, sizeof(device_name));
+		if ((recall_monitor = ast_cc_get_monitor_by_recall_core_id(cc_core_id, device_name))) {
+			monitor_instance = recall_monitor->private_data;
 			ast_copy_string(uri, monitor_instance->notify_uri, sizeof(uri));
-			ao2_ref(monitor_instance, -1);
-		}
+		}
+		ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
 	}
 
 	/* Check whether there is vxml_url, distinctive ring variables */
@@ -12536,7 +12547,10 @@
 
 	sip_pvt_lock(pvt);
 
-	create_addr(pvt, epa_entry->destination, NULL, TRUE);
+	if (create_addr(pvt, epa_entry->destination, NULL, TRUE)) {
+		dialog_unlink_all(pvt, TRUE, TRUE);
+		dialog_unref(pvt, "create_addr failed in transmit_publish. Unref dialog");
+	}
 	ast_sip_ouraddrfor(&pvt->sa.sin_addr, &pvt->ourip, pvt);
 	ast_set_flag(&pvt->flags[0], SIP_OUTGOING);
 	expires = (publish_type == SIP_PUBLISH_REMOVE) ? 0 : DEFAULT_PUBLISH_EXPIRES;
@@ -12548,6 +12562,7 @@
 
 	transmit_invite(pvt, SIP_PUBLISH, FALSE, 2, explicit_uri);
 	sip_pvt_unlock(pvt);
+	sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT);
 	dialog_unref(pvt, "Done with the sip_pvt allocated for transmitting PUBLISH");
 	return 0;
 }
@@ -15363,7 +15378,7 @@
 	if (req->rlPart2)
 		ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
 	
-	uri = get_in_brackets(tmp);
+	uri = ast_strdupa(get_in_brackets(tmp));
 
 	if (parse_uri(uri, "sip:,sips:", &uri, NULL, &domain, NULL, NULL, NULL)) {
 		ast_log(LOG_WARNING, "Not a SIP header (%s)?\n", uri);
@@ -19876,7 +19891,7 @@
 	}
 
 	if (resp != 423) {
-		ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->monitor->interface->name,
+		ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
 				"Received error response to our PUBLISH");
 		ao2_ref(monitor_instance, -1);
 		return;
@@ -19895,13 +19910,13 @@
 		pvt->expiry *= 2;
 		if (pvt->expiry < 0) {
 			/* You dork! You overflowed! */
-			ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->monitor->interface->name,
+			ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_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,
+		ast_cc_monitor_failed(cc_entry->core_id, monitor_instance->device_name,
 				"Min-Expires has non-numeric value");
 		ao2_ref(monitor_instance, -1);
 		return;
@@ -19921,12 +19936,16 @@
 	ast_assert(epa_entry != NULL);
 
 	if (resp == 401 || resp == 407) {
+		ast_string_field_set(p, theirtag, NULL);
 		if (p->options) {
 			p->options->auth_type = (resp == 401 ? WWW_AUTH : PROXY_AUTH);
 		}
 		if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp, SIP_PUBLISH, 0)) {
 			ast_log(LOG_NOTICE, "Failed to authenticate on PUBLISH to '%s'\n", get_header(&p->initreq, "From"));
-		}
+			pvt_set_needdestroy(p, "Failed to authenticate on PUBLISH");
+			sip_alreadygone(p);
+		}
+		return;
 	}
 
 	if (resp == 501 || resp == 405) {
@@ -21490,6 +21509,7 @@
 	struct sip_monitor_instance *monitor_instance = ao2_callback(sip_monitor_instances, 0,
 			find_sip_monitor_instance_by_subscription_pvt, pvt);
 	const char *status = get_body(req, "cc-state", ':');
+	struct cc_epa_entry *cc_entry;
 	char *uri;
 
 	if (!monitor_instance) {
@@ -21521,7 +21541,22 @@
 	}
 
 	ast_string_field_set(monitor_instance, notify_uri, uri);
-	ast_cc_monitor_callee_available(monitor_instance->monitor);
+	if (monitor_instance->suspension_entry) {
+		cc_entry = monitor_instance->suspension_entry->instance_data;
+		if (cc_entry->current_state == CC_CLOSED) {
+			/* If we've created a suspension entry and the current state is closed, then that means
+			 * we got a notice from the CC core earlier to suspend monitoring, but because this particular
+			 * call leg had not yet notified us that it was ready for recall, it meant that we
+			 * could not yet send a PUBLISH. Now, however, we can.
+			 */
+			construct_pidf_body(CC_CLOSED, monitor_instance->suspension_entry->body, sizeof(monitor_instance->suspension_entry->body));
+			transmit_publish(monitor_instance->suspension_entry, SIP_PUBLISH_INITIAL, monitor_instance->notify_uri);
+		} else {
+			ast_cc_monitor_callee_available(monitor_instance->core_id);
+		}
+	} else {
+		ast_cc_monitor_callee_available(monitor_instance->core_id);
+	}
 	ao2_ref(monitor_instance, -1);
 	transmit_response(pvt, "200 OK", req);
 
@@ -22676,10 +22711,8 @@
 			/* First invitation - create the channel */
 			c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL);
 			if (cc_recall_core_id != -1) {
-				char full_extension[SIPBUFSIZE];
-				snprintf(full_extension, sizeof(full_extension) - 1, "%s@%s", p->exten, p->context);
 				ast_setup_cc_recall_datastore(c, cc_recall_core_id);
-				ast_set_cc_interfaces_chanvar(c, full_extension);
+				ast_cc_agent_set_interfaces_chanvar(c);
 			}
 			*recount = 1;
 

Modified: team/group/CCSS/channels/sig_analog.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/sig_analog.c?view=diff&rev=244557&r1=244556&r2=244557
==============================================================================
--- team/group/CCSS/channels/sig_analog.c (original)
+++ team/group/CCSS/channels/sig_analog.c Wed Feb  3 14:15:00 2010
@@ -962,7 +962,7 @@
 				case AST_CC_MONITOR_ALWAYS:
 				case AST_CC_MONITOR_GENERIC:
 					ast_queue_cc_frame(p->subs[index].owner, AST_CC_GENERIC_MONITOR_TYPE,
-						analog_get_orig_dialstring(p), AST_CC_CCNR);
+						analog_get_orig_dialstring(p), AST_CC_CCNR, NULL);
 					break;
 				}
 			}

Modified: team/group/CCSS/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/sig_pri.c?view=diff&rev=244557&r1=244556&r2=244557
==============================================================================
--- team/group/CCSS/channels/sig_pri.c (original)
+++ team/group/CCSS/channels/sig_pri.c Wed Feb  3 14:15:00 2010
@@ -66,12 +66,6 @@
 };
 
 struct sig_pri_cc_monitor_instance {
-	/*!
-	 * \brief CC core monitor structure associted with this monitor instance.
-	 * \note NULL if no association established.
-	 * \note Holds a reference to the CC core monitor if not NULL.
-	 */
-	struct ast_cc_monitor *monitor;
 	/*! \brief Asterisk span D channel control structure. */
 	struct sig_pri_pri *pri;
 	/*! CC id value to use with libpri. (-1 if already canceled). */
@@ -1629,32 +1623,6 @@
 #if defined(HAVE_PRI_CCSS)
 /*!
  * \internal
- * \brief Find the CC monitor instance by CC core_id.
- * \since 1.8
- *
- * \param core_id CC core ID.
- *
- * \note
- * Since monitor_instances are refcounted, and this function returns
- * a reference to the instance, it is imperative that you decrement
- * the refcount of the instance once you have finished using it.
- *
- * \retval monitor_instance on success.
- * \retval NULL not found.
- */
-static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_core_id(int core_id)
-{
-	struct sig_pri_cc_monitor_instance finder = {
-		.core_id = core_id,
-	};
-
-	return ao2_find(sig_pri_cc_monitors, &finder, OBJ_POINTER);
-}
-#endif	/* defined(HAVE_PRI_CCSS) */
-
-#if defined(HAVE_PRI_CCSS)
-/*!
- * \internal
  * \brief Destroy the given monitor instance.
  * \since 1.8
  *
@@ -1671,10 +1639,7 @@
 		pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
 		ast_mutex_unlock(&monitor_instance->pri->lock);
 	}
-
-	if (monitor_instance->monitor) {
-		ao2_ref(monitor_instance->monitor, -1);
-	}
+	monitor_instance->pri->calls->module_unref();
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
 
@@ -1701,6 +1666,10 @@
 {
 	struct sig_pri_cc_monitor_instance *monitor_instance;
 
+	if (!pri->calls->module_ref || !pri->calls->module_unref) {
+		return NULL;
+	}
+
 	monitor_instance = ao2_alloc(sizeof(*monitor_instance) + strlen(device_name),
 		sig_pri_cc_monitor_instance_destroy);
 	if (!monitor_instance) {
@@ -1711,6 +1680,8 @@
 	monitor_instance->pri = pri;
 	monitor_instance->core_id = core_id;
 	strcpy(monitor_instance->name, device_name);
+
+	pri->calls->module_ref();
 
 	ao2_link(sig_pri_cc_monitors, monitor_instance);
 	return monitor_instance;
@@ -1773,16 +1744,20 @@
 		ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
 		sig_pri_make_cc_dialstring(pvt, dialstring, sizeof(dialstring));
 		monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
-		res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service);
+		if (!monitor) {
+			break;
+		}
+		res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service,
+			monitor);
 		if (res) {
+			monitor->cc_id = -1;
 			ao2_unlink(sig_pri_cc_monitors, monitor);
-			monitor->cc_id = -1;
-		}
-		ao2_ref(monitor, -1);
+			ao2_ref(monitor, -1);
+		}
 		break;
 	case AST_CC_MONITOR_GENERIC:
 		ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE,
-			sig_pri_get_orig_dialstring(pvt), service);
+			sig_pri_get_orig_dialstring(pvt), service, NULL);
 		/* Say it failed to force caller to cancel native CC. */
 		break;
 	}
@@ -1809,7 +1784,8 @@
 	struct ast_channel *owner;
 	struct ast_cc_config_params *cc_params;
 #if defined(HAVE_PRI_CCSS)
-	struct sig_pri_cc_monitor_instance *monitor;
+	struct ast_cc_monitor *monitor;
+	char device_name[AST_CHANNEL_NAME];
 #endif	/* defined(HAVE_PRI_CCSS) */
 	enum ast_cc_monitor_policies monitor_policy;
 	int core_id;
@@ -1837,7 +1813,8 @@
 	}
 
 #if defined(HAVE_PRI_CCSS)
-	monitor = sig_pri_find_cc_monitor_by_core_id(core_id);
+	ast_channel_get_device_name(owner, device_name, sizeof(device_name));
+	monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
 	if (monitor) {
 		/* CC monitor is already present so no need for generic CC. */
 		ao2_ref(monitor, -1);
@@ -1854,7 +1831,7 @@
 		if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
 			/* Request generic CC monitor. */
 			ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
-				sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service);
+				sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
 		}
 		break;
 	case AST_CC_MONITOR_ALWAYS:
@@ -1872,13 +1849,13 @@
 		 * Request generic CC monitor.
 		 */
 		ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
-			sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service);
+			sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
 		break;
 	case AST_CC_MONITOR_GENERIC:
 		if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
 			/* Request generic CC monitor. */
 			ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
-				sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service);
+				sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
 		}
 		break;
 	}
@@ -1917,10 +1894,9 @@
 		if (!monitor) {
 			return;
 		}
-		ao2_unlink(sig_pri_cc_monitors, monitor);
 		monitor->cc_id = -1;
 		ast_cc_monitor_failed(monitor->core_id, monitor->name,
-			sig_pri_cc_type_name);
+			"ISDN monitor got canceled by link");
 		ao2_ref(monitor, -1);
 	}
 }
@@ -2026,37 +2002,29 @@
 			case 1:/* timeout */
 				ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id,
 					sig_pri_cc_type_name);
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-				monitor->cc_id = -1;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
-					sig_pri_cc_type_name);
+					"ISDN CC request timeout");
 				break;
 			case 2:/* error */
 				ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id,
 					sig_pri_cc_type_name,
 					pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-				monitor->cc_id = -1;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
-					sig_pri_cc_type_name);
+					"ISDN CC request error");
 				break;
 			case 3:/* reject */
 				ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id,
 					sig_pri_cc_type_name,
 					pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-				monitor->cc_id = -1;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
-					sig_pri_cc_type_name);
+					"ISDN CC request reject");
 				break;
 			default:
 				ast_verb(2, "core_id:%d %s CC request unknown status %d\n",
 					monitor->core_id, sig_pri_cc_type_name,
 					subcmd->u.cc_request_rsp.status);
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-				monitor->cc_id = -1;
 				ast_cc_monitor_failed(monitor->core_id, monitor->name,
-					sig_pri_cc_type_name);
+					"ISDN CC request unknown status");
 				break;
 			}
 			ao2_ref(monitor, -1);
@@ -2070,9 +2038,7 @@
 				pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id);
 				break;
 			}
-			if (ast_cc_monitor_callee_available(monitor->monitor)) {
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-			}
+			ast_cc_monitor_callee_available(monitor->core_id);
 			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -2084,9 +2050,7 @@
 				pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id);
 				break;
 			}
-			if (ast_cc_monitor_party_b_free(monitor->core_id)) {
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-			}
+			ast_cc_monitor_party_b_free(monitor->core_id);
 			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -2098,9 +2062,7 @@
 				pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id);
 				break;
 			}
-			if (ast_cc_monitor_status_request(monitor->core_id)) {
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-			}
+			ast_cc_monitor_status_request(monitor->core_id);
 			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -2147,9 +2109,7 @@
 				pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id);
 				break;
 			}
-			if (ast_cc_monitor_stop_ringing(monitor->core_id)) {
-				ao2_unlink(sig_pri_cc_monitors, monitor);
-			}
+			ast_cc_monitor_stop_ringing(monitor->core_id);
 			ao2_ref(monitor, -1);
 			break;
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -2374,7 +2334,7 @@
 				agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
 				if (agent) {
 					ast_setup_cc_recall_datastore(owner, agent->core_id);
-					ast_cc_agent_set_interfaces_chanvar(owner, agent);
+					ast_cc_agent_set_interfaces_chanvar(owner);
 					ast_cc_agent_recalling(agent->core_id,
 						"ISDN caller is attempting recall");
 					ao2_ref(agent, -1);
@@ -4520,18 +4480,24 @@
 
 #if defined(HAVE_PRI_CCSS)
 	if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
-		struct sig_pri_cc_monitor_instance *monitor;
+		struct ast_cc_monitor *monitor;
+		char device_name[AST_CHANNEL_NAME];
 
 		/* This is a CC recall call. */
-		monitor = sig_pri_find_cc_monitor_by_core_id(core_id);
+		ast_channel_get_device_name(ast, device_name, sizeof(device_name));
+		monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
 		if (monitor) {
+			struct sig_pri_cc_monitor_instance *instance;
+
+			instance = monitor->private_data;
+
 			/* If this fails then we have monitor instance ambiguity. */
-			ast_assert(p->pri == monitor->pri);
-
-			if (pri_cc_call(p->pri->pri, monitor->cc_id, p->call, sr)) {
+			ast_assert(p->pri == instance->pri);
+
+			if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
 				/* The CC recall call failed for some reason. */
 				ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
-					monitor->name);
+					device_name);
 				ao2_ref(monitor, -1);
 				pri_rel(p->pri);
 				pri_sr_free(sr);
@@ -5416,33 +5382,11 @@
 
 #if defined(HAVE_PRI_CCSS)
 /*!
- * \brief PRI CC monitor initialization.
- * \since 1.8
- *
- * \param monitor CC core monitor control.
- * \param core_id core_id of the CC transaction.
- *
- * \details
- * Implementers must allocate the monitor's private_data
- * and initialize it to whatever may be necessary.
- *
- * \retval 0 on success
- * \retval -1 on failure.
- */
-int sig_pri_cc_monitor_init(struct ast_cc_monitor *monitor, const int core_id)
-{
-	return 0;
-}
-#endif	/* defined(HAVE_PRI_CCSS) */
-
-#if defined(HAVE_PRI_CCSS)
-/*!
  * \brief Request CCSS.
  * \since 1.8
  *
  * \param monitor CC core monitor control.
- * \param core_id core_id of the CC transaction.
- * \param parent_link The extention monitor of this monitor.
+ * \param available_timer_id Where to put the available timer scheduler id.
  * Will never be NULL for a device monitor.
  *
  * \details
@@ -5455,13 +5399,13 @@
  * \retval 0 on success
  * \retval -1 on failure.
  */
-int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link)
+int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
 {
 	struct sig_pri_cc_monitor_instance *instance;
 	int cc_mode;
 	int res;
 
-	switch (parent_link->service) {
+	switch (monitor->service_offered) {
 	case AST_CC_CCBS:
 		cc_mode = 0;/* CCBS */
 		break;
@@ -5473,21 +5417,13 @@
 		return -1;
 	}
 
-	instance = sig_pri_find_cc_monitor_by_core_id(core_id);
-	if (!instance) {
-		return -1;
-	}
-
-	/* Attach the core monitor to our monitor instance. */
-	instance->monitor = monitor;
-	ao2_ref(monitor, +1);
+	instance = monitor->private_data;
 
 	/* libpri handles it's own available timer. */
 	ast_mutex_lock(&instance->pri->lock);
 	res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
 	ast_mutex_unlock(&instance->pri->lock);
 
-	ao2_ref(instance, -1);
 	return res;
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -5498,7 +5434,6 @@
  * \since 1.8
  *
  * \param monitor CC core monitor control.
- * \param core_id core_id of the CC transaction.
  *
  * \details
  * Implementers must perform the necessary steps to suspend
@@ -5507,19 +5442,15 @@
  * \retval 0 on success
  * \retval -1 on failure.
  */
-int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id)
+int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
 {
 	struct sig_pri_cc_monitor_instance *instance;
 
-	instance = sig_pri_find_cc_monitor_by_core_id(core_id);
-	if (!instance) {
-		return -1;
-	}
+	instance = monitor->private_data;
 	ast_mutex_lock(&instance->pri->lock);
 	pri_cc_status(instance->pri->pri, instance->cc_id, 1/* busy */);
 	ast_mutex_unlock(&instance->pri->lock);
 
-	ao2_ref(instance, -1);
 	return 0;
 }
 #endif	/* defined(HAVE_PRI_CCSS) */
@@ -5530,7 +5461,6 @@
  * \since 1.8
  *
  * \param monitor CC core monitor control.

[... 3411 lines stripped ...]



More information about the svn-commits mailing list