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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 23 13:52:51 CST 2010


Author: mmichelson
Date: Tue Feb 23 13:52:47 2010
New Revision: 248482

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=248482
Log:
Address reviewboard comments.

Also converted all remaining non-t uses of ao2 functions
to use the _t_ variants.


Modified:
    team/group/CCSS/apps/app_dial.c
    team/group/CCSS/channels/chan_sip.c
    team/group/CCSS/channels/sip/include/sip.h
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/include/asterisk/xml.h
    team/group/CCSS/main/ccss.c
    team/group/CCSS/main/xml.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=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/apps/app_dial.c (original)
+++ team/group/CCSS/apps/app_dial.c Tue Feb 23 13:52:47 2010
@@ -1111,7 +1111,7 @@
 					handle_cause(AST_CAUSE_CONGESTION, &num);
 					break;
 				case AST_CONTROL_RINGING:
-					/* XXX This is a tricky area to get right when using a native
+					/* This is a tricky area to get right when using a native
 					 * CC agent. The reason is that we do the best we can to send only a
 					 * single ringing notification to the caller.
 					 *

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=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/channels/chan_sip.c (original)
+++ team/group/CCSS/channels/chan_sip.c Tue Feb 23 13:52:47 2010
@@ -860,81 +860,14 @@
 static const int HASH_DIALOG_SIZE = 563;
 #endif
 
-/*!
- * SIP PUBLISH support!
- * PUBLISH support was added to chan_sip due to its use in the call-completion
- * event package. In order to suspend and unsuspend monitoring of a called party,
- * a PUBLISH message must be sent. Rather than try to hack in PUBLISH transmission
- * and reception solely for the purposes of handling call-completion-related messages,
- * an effort has been made to create a generic framework for handling PUBLISH messages.
- *
- * There are two main components to the effort, the event publication agent (EPA) and
- * the event state compositor (ESC). Both of these terms appear in RFC 3903, and the
- * implementation in Asterisk conforms to the defintions there. An EPA is a UAC that
- * transmits PUBLISH requests. An ESC is a UAS that receives PUBLISH requests and
- * acts appropriately based on the content of those requests.
- *
- * ESC:
- * The main structure in chan_sip is the event_state_compositor. There is an
- * event_state_compositor structure for each event package supported (as of Nov 2009
- * this is only the call-completion package). The structure contains data which is
- * intrinsic to the event package itself, such as the name of the package and a set
- * of callbacks for handling incoming PUBLISH requests. In addition, the
- * event_state_compositor struct contains an ao2_container of sip_esc_entries.
- *
- * A sip_esc_entry corresponds to an entity which has sent a PUBLISH to Asterisk. We are
- * able to match the incoming PUBLISH to a sip_esc_entry using the Sip-If-Match header
- * of the message. Of course, if none is present, then a new sip_esc_entry will be created.
- *
- * Once it is determined what type of PUBLISH request has come in (from RFC 3903, it may
- * be an initial, modify, refresh, or remove), then the event package-specific callbacks
- * may be called. If your event package doesn't need to take any specific action for a
- * specific PUBLISH type, it is perfectly safe to not define the callback at all. The callback
- * only needs to take care of application-specific information. If there is a problem, it is
- * up to the callback to take care of sending an appropriate 4xx or 5xx response code. In such
- * a case, the callback should return -1. This will tell the function that called the handler
- * that an appropriate error response has been sent. If the callback returns 0, however, then
- * the caller of the callback will generate a new entity tag and send a 200 OK response.
- *
- * ESC entries are reference-counted, however as an implementor of a specific event package,
- * this should be transparent, since the reference counts are handled by the general ESC
- * framework.
- *
- * EPA:
- * The event publication agent in chan_sip is structured quite a bit differently than the
- * ESC. With an ESC, an appropriate entry has to be found based on the contents of an incoming
- * PUBLISH message. With an EPA, the application interested in sending the PUBLISH can maintain
- * a reference to the appropriate EPA entry instead. Similarly, when matching a PUBLISH response
- * to an appropriate EPA entry, the sip_pvt can maintain a reference to the corresponding
- * EPA entry. The result of this train of thought is that there is no compelling reason to
- * maintain a container of these entries.
- *
- * Instead, there is only the sip_epa_entry structure. Every sip_epa_entry has an entity tag
- * that it maintains so that subsequent PUBLISH requests will be identifiable by the ESC on
- * the far end. In addition, there is a static_data field which contains information that is
- * common to all sip_epa_entries for a specific event package. This static data includes the
- * name of the event package and callbacks for handling specific responses for outgoing PUBLISHes.
- * Also, there is a field for pointing to instance-specific data. This can include the current
- * published state or other identifying information that is specific to an instance of an EPA
- * entry of a particular event package.
- *
- * When an application wishes to send a PUBLISH request, it simply will call create_epa_entry,
- * followed by transmit_publish in order to send the PUBLISH. That's all that is necessary.
- * Like with ESC entries, sip_epa_entries are reference counted. Unlike ESC entries, though,
- * sip_epa_entries reference counts have to be maintained to some degree by the application making
- * use of the sip_epa_entry. The application will acquire a reference to the EPA entry when it
- * calls create_epa_entry. When the application has finished using the EPA entry (which may not
- * be until after several PUBLISH transactions have taken place) it must use ao2_ref to decrease
- * the reference count by 1.
- */
-
-static struct {
+static const struct {
 	enum ast_cc_service_type service;
 	const char *service_string;
 } sip_cc_service_map [] = {
-	[AST_CC_CCBS] = {AST_CC_CCBS, "BS"},
-	[AST_CC_CCNR] = {AST_CC_CCNR, "NR"},
-	[AST_CC_CCNL] = {AST_CC_CCNL, "NL"},
+	[AST_CC_NONE] = { AST_CC_NONE, "" },
+	[AST_CC_CCBS] = { AST_CC_CCBS, "BS" },
+	[AST_CC_CCNR] = { AST_CC_CCNR, "NR" },
+	[AST_CC_CCNL] = { AST_CC_CCNL, "NL" },
 };
 
 static enum ast_cc_service_type service_string_to_service_type(const char * const service_string)
@@ -948,7 +881,7 @@
 	return AST_CC_NONE;
 }
 
-static struct {
+static const struct {
 	enum sip_cc_notify_state state;
 	const char *state_string;
 } sip_cc_notify_state_map [] = {
@@ -1155,6 +1088,8 @@
 static int initialize_escs(void)
 {
 	int i, res = 0;
+	ast_log(LOG_NOTICE, "For science! esc array is %zu, which is %zu/%zu", ARRAY_LEN(event_state_compositors),
+			sizeof(event_state_compositors), sizeof(0[event_state_compositors]));
 	for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) {
 		if (!((event_state_compositors[i].compositor) =
 					ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) {
@@ -1718,33 +1653,6 @@
 	.destructor = sip_cc_agent_destructor,
 };
 
-struct sip_cc_agent_pvt {
-	int offer_timer_id;
-	/* A reference to the dialog with the caller
-	 * who is failing to reach his intended destination.
-	 */
-	struct sip_pvt *original_call;
-	/* A reference to the dialog which we will
-	 * be sending a NOTIFY on when it comes time
-	 * to send one
-	 */
-	struct sip_pvt *subscribe_pvt;
-	/* When we send a NOTIFY, we include a URI
-	 * that should be used by the caller when he
-	 * wishes to send a PUBLISH or INVITE to us.
-	 * We store that URI here.
-	 */
-	char notify_uri[SIPBUFSIZE];
-	/* When we advertise call completion to a caller,
-	 * we provide a URI for the caller to use when
-	 * he sends us a SUBSCRIBE. We store it for matching
-	 * purposes when we receive the SUBSCRIBE from the
-	 * caller.
-	 */
-	char subscribe_uri[SIPBUFSIZE];
-	char is_available;
-};
-
 static int find_by_notify_uri_helper(void *obj, void *arg, int flags)
 {
 	struct ast_cc_agent *agent = obj;
@@ -1909,28 +1817,7 @@
 	ast_free(agent_pvt);
 }
 
-/* SIP CC monitors are a bit different from generic monitors. For a generic monitor, we can
- * have a single device state subscription for the device. It's then up to the core to determine
- * which agent to service when the device becomes available. With SIP, there are separate dialogs
- * for each CC transaction being handled. The result is that if two CC requests are made to
- * the same physical device, there will be a single ast_cc_monitor allocated. However there will
- * be two SIP dialogs to keep up with for the two CC requests. The result of this is that whereas
- * generic monitoring is very device-oriented, SIP monitoring is actually very call-oriented.
- */
-
 struct ao2_container *sip_monitor_instances;
-
-struct sip_monitor_instance {
-	AST_DECLARE_STRING_FIELDS(
-		AST_STRING_FIELD(subscribe_uri);
-		AST_STRING_FIELD(notify_uri);
-		AST_STRING_FIELD(peername);
-		AST_STRING_FIELD(device_name);
-	);
-	int core_id;
-	struct sip_pvt *subscription_pvt;
-	struct sip_epa_entry *suspension_entry;
-};
 
 static int sip_monitor_instance_hash_fn(const void *obj, const int flags)
 {
@@ -5081,8 +4968,8 @@
 		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_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
+			ao2_t_ref(recall_monitor, -1, "Got the URI we need so unreffing monitor");
+		}
 	}
 
 	/* Check whether there is vxml_url, distinctive ring variables */
@@ -21737,6 +21624,8 @@
 	struct ast_xml_node *node_iterator;
 	struct ast_xml_ns *ns;
 	const char *entity;
+	const char *namespace;
+	const char presence_namespace[] = "urn:ietf:params:xml:ns:pidf";
 
 	if (!presence_node) {
 		ast_log(LOG_WARNING, "Unable to retrieve root node of the XML document\n");
@@ -21765,9 +21654,11 @@
 		return FALSE;
 	}
 
-	/* XXX Need to add code here to make sure the namespace is valid and to free it once we're done
-	 * with it
-	 */
+	namespace = ast_xml_get_ns_href(ns);
+	if (ast_strlen_zero(namespace) || strcmp(namespace, presence_namespace)) {
+		ast_log(LOG_WARNING, "PIDF document has invalid namespace value %s\n", namespace);
+		return FALSE;
+	}
 
 	if (!(child_nodes = ast_xml_node_get_children(presence_node))) {
 		ast_log(LOG_WARNING, "PIDF document has no elements as children of 'presence'. Invalid\n");
@@ -21871,6 +21762,7 @@
 	struct ast_xml_node *status_node;
 	struct ast_xml_node *status_children;
 	struct ast_xml_node *basic_node;
+	int res = 0;
 
 	if (!agent) {
 		ast_log(LOG_WARNING, "Could not find agent using uri '%s'\n", uri);
@@ -21881,9 +21773,8 @@
 	agent_pvt = agent->private_data;
 
 	if (sip_pidf_validate(req, &pidf_doc) == FALSE) {
-		transmit_response(pvt, "400 Bad Request", req);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	/* It's important to note that the PIDF validation routine has no knowledge
@@ -21895,18 +21786,14 @@
 	presence_node = ast_xml_get_root(pidf_doc);
 	if (!(presence_children = ast_xml_node_get_children(presence_node))) {
 		ast_log(LOG_WARNING, "No tuples within presence element.\n");
-		transmit_response(pvt, "400 Bad Request", req);
-		ast_xml_close(pidf_doc);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	if (!(tuple_node = ast_xml_find_element(presence_children, "tuple", NULL, NULL))) {
 		ast_log(LOG_NOTICE, "Couldn't find tuple node?\n");
-		transmit_response(pvt, "400 Bad Request", req);
-		ast_xml_close(pidf_doc);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	/* We already made sure that the tuple has a status node when we validated the PIDF
@@ -21917,29 +21804,22 @@
 
 	if (!(status_children = ast_xml_node_get_children(status_node))) {
 		ast_log(LOG_WARNING, "No basic elements within status element.\n");
-		transmit_response(pvt, "400 Bad Request", req);
-		ast_xml_close(pidf_doc);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	if (!(basic_node = ast_xml_find_element(status_children, "basic", NULL, NULL))) {
 		ast_log(LOG_WARNING, "Couldn't find basic node?\n");
-		transmit_response(pvt, "400 Bad Request", req);
-		ast_xml_close(pidf_doc);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	basic_status = ast_xml_get_text(basic_node);
 
 	if (ast_strlen_zero(basic_status)) {
 		ast_log(LOG_NOTICE, "NOthing in basic node?\n");
-		transmit_response(pvt, "400 Bad Request", req);
-		ast_xml_free_text(basic_status);
-		ast_xml_close(pidf_doc);
-		ao2_ref(agent, -1);
-		return -1;
+		res = -1;
+		goto cc_publish_cleanup;
 	}
 
 	if (!strcmp(basic_status, "open")) {
@@ -21951,14 +21831,21 @@
 		ast_cc_agent_caller_busy(agent->core_id, "Received PUBLISH stating SIP caller %s is busy",
 				agent->device_name);
 	} else {
-		ast_log(LOG_NOTICE, "BS basic content?\n");
+		ast_log(LOG_NOTICE, "Invalid content in basic element: %s\n", basic_status);
+	}
+
+cc_publish_cleanup:
+	if (basic_status) {
+		ast_xml_free_text(basic_status);
+	}
+	if (pidf_doc) {
+		ast_xml_close(pidf_doc);
+	}
+	ao2_ref(agent, -1);
+	if (res) {
 		transmit_response(pvt, "400 Bad Request", req);
 	}
-
-	ast_xml_free_text(basic_status);
-	ast_xml_close(pidf_doc);
-	ao2_ref(agent, -1);
-	return 0;
+	return res;
 }
 
 #endif /* HAVE_LIBXML2 */

Modified: team/group/CCSS/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/sip/include/sip.h?view=diff&rev=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/channels/sip/include/sip.h (original)
+++ team/group/CCSS/channels/sip/include/sip.h Tue Feb 23 13:52:47 2010
@@ -153,7 +153,7 @@
  *  \todo This string should be set dynamically. We only support REFER and SUBSCRIBE if we have
  *  allowsubscribe and allowrefer on in sip.conf.
  */
-#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"
+#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH"
 
 /*! \brief SIP Extensions we support
  *  \note This should be generated based on the previous array
@@ -1291,6 +1291,74 @@
 };
 
 /*!
+ * SIP PUBLISH support!
+ * PUBLISH support was added to chan_sip due to its use in the call-completion
+ * event package. In order to suspend and unsuspend monitoring of a called party,
+ * a PUBLISH message must be sent. Rather than try to hack in PUBLISH transmission
+ * and reception solely for the purposes of handling call-completion-related messages,
+ * an effort has been made to create a generic framework for handling PUBLISH messages.
+ *
+ * There are two main components to the effort, the event publication agent (EPA) and
+ * the event state compositor (ESC). Both of these terms appear in RFC 3903, and the
+ * implementation in Asterisk conforms to the defintions there. An EPA is a UAC that
+ * transmits PUBLISH requests. An ESC is a UAS that receives PUBLISH requests and
+ * acts appropriately based on the content of those requests.
+ *
+ * ESC:
+ * The main structure in chan_sip is the event_state_compositor. There is an
+ * event_state_compositor structure for each event package supported (as of Nov 2009
+ * this is only the call-completion package). The structure contains data which is
+ * intrinsic to the event package itself, such as the name of the package and a set
+ * of callbacks for handling incoming PUBLISH requests. In addition, the
+ * event_state_compositor struct contains an ao2_container of sip_esc_entries.
+ *
+ * A sip_esc_entry corresponds to an entity which has sent a PUBLISH to Asterisk. We are
+ * able to match the incoming PUBLISH to a sip_esc_entry using the Sip-If-Match header
+ * of the message. Of course, if none is present, then a new sip_esc_entry will be created.
+ *
+ * Once it is determined what type of PUBLISH request has come in (from RFC 3903, it may
+ * be an initial, modify, refresh, or remove), then the event package-specific callbacks
+ * may be called. If your event package doesn't need to take any specific action for a
+ * specific PUBLISH type, it is perfectly safe to not define the callback at all. The callback
+ * only needs to take care of application-specific information. If there is a problem, it is
+ * up to the callback to take care of sending an appropriate 4xx or 5xx response code. In such
+ * a case, the callback should return -1. This will tell the function that called the handler
+ * that an appropriate error response has been sent. If the callback returns 0, however, then
+ * the caller of the callback will generate a new entity tag and send a 200 OK response.
+ *
+ * ESC entries are reference-counted, however as an implementor of a specific event package,
+ * this should be transparent, since the reference counts are handled by the general ESC
+ * framework.
+ *
+ * EPA:
+ * The event publication agent in chan_sip is structured quite a bit differently than the
+ * ESC. With an ESC, an appropriate entry has to be found based on the contents of an incoming
+ * PUBLISH message. With an EPA, the application interested in sending the PUBLISH can maintain
+ * a reference to the appropriate EPA entry instead. Similarly, when matching a PUBLISH response
+ * to an appropriate EPA entry, the sip_pvt can maintain a reference to the corresponding
+ * EPA entry. The result of this train of thought is that there is no compelling reason to
+ * maintain a container of these entries.
+ *
+ * Instead, there is only the sip_epa_entry structure. Every sip_epa_entry has an entity tag
+ * that it maintains so that subsequent PUBLISH requests will be identifiable by the ESC on
+ * the far end. In addition, there is a static_data field which contains information that is
+ * common to all sip_epa_entries for a specific event package. This static data includes the
+ * name of the event package and callbacks for handling specific responses for outgoing PUBLISHes.
+ * Also, there is a field for pointing to instance-specific data. This can include the current
+ * published state or other identifying information that is specific to an instance of an EPA
+ * entry of a particular event package.
+ *
+ * When an application wishes to send a PUBLISH request, it simply will call create_epa_entry,
+ * followed by transmit_publish in order to send the PUBLISH. That's all that is necessary.
+ * Like with ESC entries, sip_epa_entries are reference counted. Unlike ESC entries, though,
+ * sip_epa_entries reference counts have to be maintained to some degree by the application making
+ * use of the sip_epa_entry. The application will acquire a reference to the EPA entry when it
+ * calls create_epa_entry. When the application has finished using the EPA entry (which may not
+ * be until after several PUBLISH transactions have taken place) it must use ao2_ref to decrease
+ * the reference count by 1.
+ */
+
+/*!
  * \brief The states that can be represented in a SIP call-completion PUBLISH
  */
 enum sip_cc_publish_state {
@@ -1530,4 +1598,43 @@
 	void *event_specific_data;
 };
 
+struct sip_cc_agent_pvt {
+	int offer_timer_id;
+	/* A reference to the dialog with the caller
+	 * who is failing to reach his intended destination.
+	 */
+	struct sip_pvt *original_call;
+	/* A reference to the dialog which we will
+	 * be sending a NOTIFY on when it comes time
+	 * to send one
+	 */
+	struct sip_pvt *subscribe_pvt;
+	/* When we send a NOTIFY, we include a URI
+	 * that should be used by the caller when he
+	 * wishes to send a PUBLISH or INVITE to us.
+	 * We store that URI here.
+	 */
+	char notify_uri[SIPBUFSIZE];
+	/* When we advertise call completion to a caller,
+	 * we provide a URI for the caller to use when
+	 * he sends us a SUBSCRIBE. We store it for matching
+	 * purposes when we receive the SUBSCRIBE from the
+	 * caller.
+	 */
+	char subscribe_uri[SIPBUFSIZE];
+	char is_available;
+};
+
+struct sip_monitor_instance {
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(subscribe_uri);
+		AST_STRING_FIELD(notify_uri);
+		AST_STRING_FIELD(peername);
+		AST_STRING_FIELD(device_name);
+	);
+	int core_id;
+	struct sip_pvt *subscription_pvt;
+	struct sip_epa_entry *suspension_entry;
+};
+
 #endif

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=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Tue Feb 23 13:52:47 2010
@@ -1200,7 +1200,7 @@
  * \param debug A debug message to print to the CC log
  * \return void
  */
-int ast_cc_monitor_failed(int core_id, const char * const monitor_name, const char * const debug);
+int __attribute__((format(printf, 3, 4))) ast_cc_monitor_failed(int core_id, const char * const monitor_name, const char * const debug, ...);
 
 /* END STATE CHANGE API */
 

Modified: team/group/CCSS/include/asterisk/xml.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/xml.h?view=diff&rev=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/include/asterisk/xml.h (original)
+++ team/group/CCSS/include/asterisk/xml.h Tue Feb 23 13:52:47 2010
@@ -99,6 +99,7 @@
  */
 struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue);
 struct ast_xml_ns *ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name);
+const char *ast_xml_get_ns_href(struct ast_xml_ns *ns);
 
 /*! \brief Get an element content string.
  *  \param node Node from where to get the string.

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Tue Feb 23 13:52:47 2010
@@ -405,7 +405,8 @@
 {
 	struct cc_callback_helper helper = {.function = function, .args = args, .type = type};
 	struct cc_core_instance *core_instance;
-	if ((core_instance = ao2_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper))) {
+	if ((core_instance = ao2_t_callback(cc_core_instances, flags, cc_agent_callback_helper, &helper,
+					"Calling provided agent callback function"))) {
 		struct ast_cc_agent *agent = cc_ref(core_instance->agent, "An outside entity needs the agent");
 		cc_unref(core_instance, "agent callback done with the core_instance");
 		return agent;
@@ -1028,7 +1029,7 @@
 {
 	struct generic_monitor_instance_list finder = {.device_name = device_name};
 
-	return ao2_find(generic_monitors, &finder, OBJ_POINTER);
+	return ao2_t_find(generic_monitors, &finder, OBJ_POINTER, "Finding generic monitor instance list");
 }
 
 static void generic_monitor_instance_list_destructor(void *obj)
@@ -1046,7 +1047,8 @@
 static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata);
 static struct generic_monitor_instance_list *create_new_generic_list(struct ast_cc_monitor *monitor)
 {
-	struct generic_monitor_instance_list *generic_list = ao2_alloc(sizeof(*generic_list), generic_monitor_instance_list_destructor);
+	struct generic_monitor_instance_list *generic_list = ao2_t_alloc(sizeof(*generic_list),
+			generic_monitor_instance_list_destructor, "allocate generic monitor instance list");
 
 	if (!generic_list) {
 		return NULL;
@@ -1064,7 +1066,7 @@
 		return NULL;
 	}
 	generic_list->current_state = ast_device_state(monitor->interface->device_name);
-	ao2_link(generic_monitors, generic_list);
+	ao2_t_link(generic_monitors, generic_list, "linking new generic monitor instance list");
 	return generic_list;
 }
 
@@ -1722,11 +1724,12 @@
 
 	ast_str_set(&str, 0, "%s@%s", exten, context);
 
-	if (!(cc_interface = ao2_alloc(sizeof(*cc_interface) + ast_str_strlen(str), cc_interface_destroy))) {
+	if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + ast_str_strlen(str), cc_interface_destroy,
+					"Allocating new ast_cc_interface"))) {
 		return NULL;
 	}
 
-	if (!(monitor = ao2_alloc(sizeof(*monitor), cc_monitor_destroy))) {
+	if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
 		cc_unref(cc_interface, "failed to allocate the monitor, so unref the interface");
 		return NULL;
 	}
@@ -1883,7 +1886,8 @@
 	size_t device_name_len = strlen(device_name);
 	int parent_id = cc_data->parent_interface_id;
 
-	if (!(cc_interface = ao2_alloc(sizeof(*cc_interface) + device_name_len, cc_interface_destroy))) {
+	if (!(cc_interface = ao2_t_alloc(sizeof(*cc_interface) + device_name_len, cc_interface_destroy,
+					"Allocating new ast_cc_interface"))) {
 		call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
 		return NULL;
 	}
@@ -1894,7 +1898,7 @@
 		return NULL;
 	}
 
-	if (!(monitor = ao2_alloc(sizeof(*monitor), cc_monitor_destroy))) {
+	if (!(monitor = ao2_t_alloc(sizeof(*monitor), cc_monitor_destroy, "Allocating new ast_cc_monitor"))) {
 		cc_unref(cc_interface, "Failed to allocate monitor, unref interface");
 		call_destructor_with_no_monitor(cc_data->monitor_type, cc_data->private_data);
 		return NULL;
@@ -2189,7 +2193,8 @@
 	struct ast_cc_agent *agent;
 	struct ast_cc_config_params *cc_params;
 
-	if (!(agent = ao2_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy))) {
+	if (!(agent = ao2_t_alloc(sizeof(*agent) + strlen(caller_name), agent_destroy,
+					"Allocating new ast_cc_agent"))) {
 		return NULL;
 	}
 
@@ -2934,9 +2939,7 @@
 	int debuglen;
 	char dummy[1];
 	va_list aq;
-	struct cc_state_change_args *args = ast_calloc(1, sizeof(*args) +
-			(ast_strlen_zero(debug) ? 0 : strlen(debug)));
-
+	struct cc_state_change_args *args;
 	/* This initial call to vsnprintf is simply to find what the
 	 * size of the string needs to be
 	 */
@@ -3472,7 +3475,7 @@
 
 struct ast_cc_monitor_failure_data {
 	const char *device_name;
-	const char *debug;
+	char *debug;
 	int core_id;
 };
 
@@ -3524,10 +3527,11 @@
 	return 0;
 }
 
-int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const debug)
+int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const debug, ...)
 {
 	struct ast_cc_monitor_failure_data *failure_data;
 	int res;
+	va_list ap;
 
 	if (!(failure_data = ast_calloc(1, sizeof(*failure_data)))) {
 		return -1;
@@ -3538,11 +3542,14 @@
 		return -1;
 	}
 
-	if (!(failure_data->debug = ast_strdup(debug))) {
+	va_start(ap, debug);
+	if (vasprintf(&failure_data->debug, debug, ap) == -1) {
+		va_end(ap);
 		ast_free((char *)failure_data->device_name);
 		ast_free(failure_data);
 		return -1;
 	}
+	va_end(ap);
 
 	failure_data->core_id = core_id;
 
@@ -4074,8 +4081,8 @@
 	struct ao2_iterator core_iter = ao2_iterator_init(cc_core_instances, 0);
 	struct cc_core_instance *core_instance;
 
-	for (; (core_instance = ao2_iterator_next(&core_iter)); cc_unref(core_instance,
-				"CLI tab completion iteration")) {
+	for (; (core_instance = ao2_t_iterator_next(&core_iter, "Next core instance"));
+			cc_unref(core_instance, "CLI tab completion iteration")) {
 		char core_id_str[20];
 		snprintf(core_id_str, sizeof(core_id_str), "%d", core_instance->core_id);
 		if (!strncmp(word, core_id_str, wordlen) && ++which > state) {

Modified: team/group/CCSS/main/xml.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/xml.c?view=diff&rev=248482&r1=248481&r2=248482
==============================================================================
--- team/group/CCSS/main/xml.c (original)
+++ team/group/CCSS/main/xml.c Tue Feb 23 13:52:47 2010
@@ -189,6 +189,11 @@
 	return (struct ast_xml_ns *) ns;
 }
 
+const char *ast_xml_get_ns_href(struct ast_xml_ns *ns)
+{
+	return (const char *) ((xmlNsPtr) ns)->href;
+}
+
 const char *ast_xml_get_text(struct ast_xml_node *node)
 {
 	if (!node) {




More information about the asterisk-commits mailing list