[asterisk-commits] kharwell: branch kharwell/pimp_sip_state r388665 - in /team/kharwell/pimp_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon May 13 18:02:17 CDT 2013


Author: kharwell
Date: Mon May 13 18:02:14 2013
New Revision: 388665

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388665
Log:
changed pidf xml provider to use pjsip

Modified:
    team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
    team/kharwell/pimp_sip_state/res/res_sip_exten_state.c
    team/kharwell/pimp_sip_state/res/res_sip_providers/include/res_sip_providers.h
    team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c

Modified: team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h?view=diff&rev=388665&r1=388664&r2=388665
==============================================================================
--- team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h (original)
+++ team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h Mon May 13 18:02:14 2013
@@ -25,6 +25,7 @@
 #include "asterisk/pbx.h"
 #include "asterisk/presencestate.h"
 
+
 /*!
  * \brief Contains information pertaining to extension/device state changes.
  */
@@ -49,6 +50,8 @@
 	const char *type;
 	/*! Subtype of the body, ex: "pidf+xml" */
 	const char *subtype;
+	/*! Type/Subtype appended together - set internally */
+	char body_type[50];
 
 	/*!
 	 * \brief Create the body text of a NOTIFY request.
@@ -68,4 +71,18 @@
 	AST_LIST_ENTRY(ast_sip_exten_state_provider) next;
 };
 
+/*!
+ * \brief Registers an extension state provider.
+ *
+ * \param obj An extension state provider
+ */
+int ast_sip_register_exten_state_provider(struct ast_sip_exten_state_provider *obj);
+
+/*!
+ * \brief Unregisters an extension state provider.
+ *
+ * \param obj An extension state provider
+ */
+void ast_sip_unregister_exten_state_provider(struct ast_sip_exten_state_provider *obj);
+
 #endif

Modified: team/kharwell/pimp_sip_state/res/res_sip_exten_state.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/res/res_sip_exten_state.c?view=diff&rev=388665&r1=388664&r2=388665
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_exten_state.c (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_exten_state.c Mon May 13 18:02:14 2013
@@ -45,7 +45,7 @@
 
 AST_RWLIST_HEAD_STATIC(providers, ast_sip_exten_state_provider);
 
-static int register_sip_exten_state_provider(struct ast_sip_exten_state_provider *obj)
+int ast_sip_register_exten_state_provider(struct ast_sip_exten_state_provider *obj)
 {
 	SCOPED_LOCK(lock, &providers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
 
@@ -66,13 +66,17 @@
 		    obj->event_name);
 		return -1;
 	}
-	
+	strncpy(obj->body_type, obj->type, sizeof(obj->body_type));
+	strncat(obj->body_type, "/", 1);
+	strncat(obj->body_type, obj->subtype, sizeof(obj->body_type) - 
+		strlen(obj->body_type));
+
 	AST_RWLIST_INSERT_TAIL(&providers, obj, next);
 	ast_module_ref(ast_module_info->self);
 	return 0;
 }
 
-static void unregister_sip_exten_state_provider(struct ast_sip_exten_state_provider *obj)
+void ast_sip_unregister_exten_state_provider(struct ast_sip_exten_state_provider *obj)
 {
 	struct ast_sip_exten_state_provider *i;
 	SCOPED_LOCK(lock, &providers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
@@ -92,12 +96,10 @@
  */
 static struct ast_sip_exten_state_provider *provider_by_accept(const char *accept)
 {
-	struct ast_str *type = ast_str_alloca(BODY_TYPE_SIZE);
 	struct ast_sip_exten_state_provider *i;
 	SCOPED_LOCK(lock, &providers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&providers, i, next) {
-		ast_str_set(&type, -1, "%s/%s", i->type, i->subtype);
-		if (!strcmp(ast_str_buffer(type), accept)) {
+		if (!strcmp(i->body_type, accept)) {
 			return i;
 		}
 	}
@@ -175,6 +177,8 @@
 	char context[AST_MAX_CONTEXT];
 	/*! Extension within the context to receive updates from */
 	char exten[AST_MAX_EXTENSION];
+	/*! The last known extension state */
+	enum ast_extension_states last_exten_state;
 };
 
 static void exten_state_subscription_destructor(void *obj)
@@ -235,11 +239,13 @@
 		return NULL;
 	}
 
+	
 	if (!(exten_state_sub->sip_sub = ast_sip_create_subscription(handler, role, endpoint, rdata))) {
 		ast_log(LOG_WARNING, "Unable to create SIP subscription for endpoint %s\n",
 			ast_sorcery_object_get_id(endpoint));
 		return NULL;
 	}
+	exten_state_sub->last_exten_state = -3;
 
 	ao2_ref(exten_state_sub, +1);
 	return exten_state_sub;
@@ -375,9 +381,15 @@
 static int state_changed(char *context, char *exten,
 			 struct ast_state_cb_info *info, void *data)
 {
-	struct notify_task_data *task_data = alloc_notify_task_data(data);
-
-	if (!task_data) {
+	struct notify_task_data *task_data;
+	struct exten_state_subscription *exten_state_sub = data;
+
+	if (exten_state_sub->last_exten_state == info->exten_state) {
+		return 0;
+	}
+	exten_state_sub->last_exten_state = info->exten_state;	
+
+	if (!(task_data = alloc_notify_task_data(exten_state_sub))) {
 		return -1;
 	}
 
@@ -627,19 +639,16 @@
 		struct ast_sip_subscription_handler *handler =
 			ao2_find(sub_handlers, i->event_name, OBJ_NOLOCK | OBJ_KEY);
 
-		struct ast_str *type = ast_str_alloca(BODY_TYPE_SIZE);
-		ast_str_set(&type, -1, "%s/%s", i->type, i->subtype);
-
 		if (handler) {
 			/* if handler exists just assign those accept values to
 			   it from the provider that have not already been set */
-			add_accept(handler->accept, ast_str_buffer(type));
+			add_accept(handler->accept, i->body_type);
 			continue;
 		}
 
 		/* if handler does not exist yet, create it and add to
 		   container - note accept values assigned in create */
-		if ((handler = create_sub_handler(i->event_name, ast_str_buffer(type)))) {
+		if ((handler = create_sub_handler(i->event_name, i->body_type))) {
 			ao2_link(sub_handlers, handler);
 		}
 	}
@@ -656,7 +665,7 @@
 	int *count = arg;
 
 	if (ast_sip_register_subscription_handler(handler)) {
-		ast_log(LOG_WARNING, "Unable to register subscription handler %s",
+		ast_log(LOG_WARNING, "Unable to register subscription handler %s\n",
 			handler->event_name);
 	} else {
 		/* if at least one handler registers we will
@@ -691,9 +700,9 @@
 	   'application/pidf+xml' and then later try to re-register 'presence'
 	   along with 'application/xpidf'). if pjsip ever gets modified these
 	   can be moved to their respective module files */
-	register_sip_exten_state_provider(ast_sip_pidf_xml_provider());
-	register_sip_exten_state_provider(ast_sip_xpidf_xml_provider());
-	register_sip_exten_state_provider(ast_sip_cpim_pidf_xml_provider());
+	ast_sip_register_pidf_xml_provider();
+	ast_sip_register_xpidf_xml_provider();
+	ast_sip_register_cpim_pidf_xml_provider();
 
 	/* create the subscription handlers based upon the providers */
 	create_sub_handlers();
@@ -712,9 +721,9 @@
 		     unregister_sub_handlers, NULL);
 
 	/* unregister providers here, again due to pjsip limitation mentioned above */
-	unregister_sip_exten_state_provider(ast_sip_cpim_pidf_xml_provider());
-	unregister_sip_exten_state_provider(ast_sip_xpidf_xml_provider());
-	unregister_sip_exten_state_provider(ast_sip_pidf_xml_provider());
+	ast_sip_unregister_pidf_xml_provider();
+	ast_sip_unregister_xpidf_xml_provider();
+	ast_sip_unregister_cpim_pidf_xml_provider();
 
 	ao2_cleanup(sub_handlers);
 

Modified: team/kharwell/pimp_sip_state/res/res_sip_providers/include/res_sip_providers.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/res/res_sip_providers/include/res_sip_providers.h?view=diff&rev=388665&r1=388664&r2=388665
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_providers/include/res_sip_providers.h (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_providers/include/res_sip_providers.h Mon May 13 18:02:14 2013
@@ -35,8 +35,13 @@
    added here in order to be accessible by res_sip_extern_state.
 */
 
-struct ast_sip_exten_state_provider *ast_sip_pidf_xml_provider(void);
-struct ast_sip_exten_state_provider *ast_sip_xpidf_xml_provider(void);
-struct ast_sip_exten_state_provider *ast_sip_cpim_pidf_xml_provider(void);
+void ast_sip_register_pidf_xml_provider(void);
+void ast_sip_unregister_pidf_xml_provider(void);
+
+void ast_sip_register_xpidf_xml_provider(void);
+void ast_sip_unregister_xpidf_xml_provider(void);
+
+void ast_sip_register_cpim_pidf_xml_provider(void);
+void ast_sip_unregister_cpim_pidf_xml_provider(void);
 
 #endif

Modified: team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c?view=diff&rev=388665&r1=388664&r2=388665
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c Mon May 13 18:02:14 2013
@@ -24,11 +24,12 @@
 	<support_level>core</support_level>
  ***/
 
-
-
 #include "asterisk.h"
 #include "asterisk/res_sip_exten_state.h"
 #include "include/res_sip_providers.h"
+
+#include <pjsip_simple.h>
+#include <pjlib.h>
 
 enum state {
 	NOTIFY_OPEN,
@@ -82,67 +83,175 @@
 	}
 }
 
-/* static int pool_initialized = 0; */
-/* static pj_caching_pool caching_pool; */
-
-/* static pj_pool_t *create_pj_pool(void) */
-/* { */
-/* 	if (!pool_initialized) { */
-/* 		pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0); */
-/* 	} */
-
-/* 	pj_pool_t *pool = pj_pool_create(&caching_pool.factory, "SIP", 1024, 1024, NULL); */
-/* 	if (!memory_pool) { */
-/* 		ast_log(LOG_ERROR, "Failed to create memory pool for SIP. Aborting load\n"); */
-/* 		goto error; */
-/* 	} */
-/* } */
+/*! Factory used to initialize memory allocation pool. */
+static pj_caching_pool *caching_pool = NULL;
+
+/*! Pool used for memory allocation. */
+static pj_pool_t *pool = NULL;
+
+static void pool_destructor(void *obj)
+{
+	struct pj_caching_pool *cp = obj;
+	if (cp) {
+		pj_caching_pool_destroy(cp);
+		caching_pool = NULL;
+	}
+}
+
+static void pool_create(void)
+{
+	caching_pool = ao2_alloc(sizeof(*caching_pool), pool_destructor);
+
+	pj_caching_pool_init(caching_pool,
+			     &pj_pool_factory_default_policy, 0);
+
+	if (!(pool = pj_pool_create(&caching_pool->factory, "pidf",
+				    1024, 1024, NULL))) {
+		ast_log(LOG_WARNING, "Failed to create memory pool for PIDF\n");
+		pj_caching_pool_destroy(caching_pool);
+	}
+}
+
+static void pool_ref(int ref)
+{
+	if (!caching_pool) {
+		pool_create();
+	} else {
+		ao2_ref(caching_pool, ref);
+	}
+}
+
+static void add_attr(pj_xml_node *node, const pj_str_t* name,
+		      const pj_str_t* value)
+{
+	pj_xml_attr *attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);
+
+	pj_strdup(pool, &attr->name, name);
+	pj_strdup(pool, &attr->value, value);
+	attr->value = *value;
+
+	pj_xml_add_attr(node, attr);
+}
+
+static pj_xml_node *create_node(const char* name)
+{
+	pj_xml_node *node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
+
+	pj_list_init(&node->attr_head);
+	pj_list_init(&node->node_head);
+
+	pj_strdup2(pool, &node->name, name);
+
+	node->content.ptr = NULL;
+	node->content.slen = 0;
+
+	return node;
+}
+
+/*!
+ * \internal
+ * \brief Adds non standard elements to the xml body
+ *
+ * This is some code that was part of the original chan_sip implementation
+ * that is not part of the RFC 3863 definition, but we are keeping available
+ * for backward compatability. The original comment stated that Eyebeam 
+ * supports this format.
+
+ */
+static void add_non_standard(pj_xml_node *node, const char *pidfstate)
+{
+	static const pj_str_t XMLNS_PP = { "xmlns:pp", 8 };
+	static const pj_str_t XMLNS_PERSON = { "urn:ietf:params:xml:ns:pidf:person", 34 };
+
+	static const pj_str_t XMLNS_ES = { "xmlns:es", 8 };
+	static const pj_str_t XMLNS_RPID_STATUS = { "urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status", 51 };
+
+	static const pj_str_t XMLNS_EP = { "xmlns:ep", 8 };
+	static const pj_str_t XMLNS_RPID_PERSON = { "urn:ietf:params:xml:ns:pidf:rpid:rpid-person", 44 };
+
+	pj_xml_node *person = create_node("pp:person");
+	pj_xml_node *status = create_node("status");
+
+	if (pidfstate[0] != '-') {
+		pj_xml_node *activities = create_node("ep:activities");
+		pj_strdup2(pool, &activities->content, "ep:");
+		pj_strcat2(&activities->content, pidfstate);
+		pj_xml_add_node(status, activities);
+	}
+
+	add_attr(node, &XMLNS_PP, &XMLNS_PERSON);
+	add_attr(node, &XMLNS_ES, &XMLNS_RPID_STATUS);
+	add_attr(node, &XMLNS_EP, &XMLNS_RPID_PERSON);
+
+	pj_xml_add_node(person, status);
+	pj_xml_add_node(node, person);
+}
 
 static int pidf_xml_create_body(struct ast_sip_exten_state_data *data, const char *local,
 				const char *remote, struct ast_str **body_text)
 {
+	pjpidf_pres *pres;
+	pjpidf_tuple *tuple;
+
+	pj_str_t entity, note, id, contact, priority;
+
 	char *statestring = NULL, *pidfstate = NULL, *pidfnote = NULL;
-	int local_state;
+	int local_state, size;
 
 	exten_state_to_str(data->exten_state, &statestring, &pidfstate,
 			   &pidfnote, &local_state);
 
-	ast_str_append(body_text, 0,
-		       "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
-		       "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\"\n"
-		       "xmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\n"
-		       "xmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\n"
-		       "xmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\n"
-		       "entity=\"%s\">\n", local);
-
-	ast_str_append(body_text, 0, "<pp:person><status>\n");
-	if (pidfstate[0] != '-') {
-		ast_str_append(body_text, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
-	}
-	ast_str_append(body_text, 0, "</status></pp:person>\n");
-	ast_str_append(body_text, 0, "<note>%s</note>\n", pidfnote);
-	ast_str_append(body_text, 0, "<tuple id=\"%s\">\n", data->exten); /* Tuple start */
-	ast_str_append(body_text, 0, "<contact priority=\"1\">%s</contact>\n", remote);
-	if (pidfstate[0] == 'b') { /* Busy? Still open ... */
-		ast_str_append(body_text, 0, "<status><basic>open</basic></status>\n");
-	} else {
-		ast_str_append(body_text, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
-	}
-	ast_str_append(body_text, 0, "</tuple>\n</presence>\n");
+	if (!(pres = pjpidf_create(pool, pj_cstr(&entity, local)))) {
+		ast_log(LOG_WARNING, "Unable to create PIDF presence\n");
+		return -1;
+	}
+
+	add_non_standard(pres, pidfstate);
+
+	if (!pjpidf_pres_add_note(pool, pres, pj_cstr(&note, pidfnote))) {
+		ast_log(LOG_WARNING, "Unable to add note to PIDF presence\n");
+		return -1;
+	}
+
+	if (!(tuple = pjpidf_pres_add_tuple(pool, pres, pj_cstr(&id, data->exten)))) {
+		ast_log(LOG_WARNING, "Unable to create PIDF tuple\n");
+		return -1;
+	}
+
+	pjpidf_tuple_set_contact(pool, tuple, pj_cstr(&contact, remote));
+	pjpidf_tuple_set_contact_prio(pool, tuple, pj_cstr(&priority, "1"));
+	pjpidf_status_set_basic_open(pjpidf_tuple_get_status(tuple),
+				     (pidfstate[0] == 'b') || (local_state != NOTIFY_CLOSED));
+
+	if (!(size = pjpidf_print(pres, ast_str_buffer(*body_text),
+				  ast_str_size(*body_text)))) {
+		ast_log(LOG_WARNING, "PIDF body text too large\n");
+		return -1;
+	}
+
+	*(ast_str_buffer(*body_text) + size) = '\0';
+	ast_str_update(*body_text);
 
 	return 0;
 }
 
-static struct ast_sip_exten_state_provider _pidf_xml_provider = {
+static struct ast_sip_exten_state_provider pidf_xml_provider = {
 	.event_name = "presence",
 	.type = "application",
 	.subtype = "pidf+xml",
 	.create_body = pidf_xml_create_body
 };
 
-struct ast_sip_exten_state_provider *ast_sip_pidf_xml_provider(void)
-{
-	return &_pidf_xml_provider;
+void ast_sip_register_pidf_xml_provider(void)
+{
+	pool_ref(+1);
+	ast_sip_register_exten_state_provider(&pidf_xml_provider);
+}
+
+void ast_sip_unregister_pidf_xml_provider(void)
+{
+	ast_sip_unregister_exten_state_provider(&pidf_xml_provider);
+	pool_ref(-1);
 }
 
 static int xpidf_xml_create_body(struct ast_sip_exten_state_data *data, const char *local,
@@ -172,24 +281,40 @@
 	return 0;
 }
 
-static struct ast_sip_exten_state_provider _xpidf_xml_provider = {
+static struct ast_sip_exten_state_provider xpidf_xml_provider = {
 	.event_name = "presence",
 	.type = "application",
 	.subtype = "xpidf+xml",
 	.create_body = xpidf_xml_create_body
 };
 
-struct ast_sip_exten_state_provider *ast_sip_xpidf_xml_provider(void) {
-	return &_xpidf_xml_provider;
-}
-
-static struct ast_sip_exten_state_provider _cpim_pidf_xml_provider = {
+void ast_sip_register_xpidf_xml_provider(void)
+{
+	pool_ref(+1);
+	ast_sip_register_exten_state_provider(&xpidf_xml_provider);
+}
+
+void ast_sip_unregister_xpidf_xml_provider(void)
+{
+	ast_sip_unregister_exten_state_provider(&xpidf_xml_provider);
+	pool_ref(-1);
+}
+
+static struct ast_sip_exten_state_provider cpim_pidf_xml_provider = {
 	.event_name = "presence",
 	.type = "application",
 	.subtype = "cpim-pidf+xml",
 	.create_body = xpidf_xml_create_body
 };
 
-struct ast_sip_exten_state_provider *ast_sip_cpim_pidf_xml_provider(void) {
-	return &_cpim_pidf_xml_provider;
-}
+void ast_sip_register_cpim_pidf_xml_provider(void)
+{
+	pool_ref(+1);
+	ast_sip_register_exten_state_provider(&cpim_pidf_xml_provider);
+}
+
+void ast_sip_unregister_cpim_pidf_xml_provider(void)
+{
+	ast_sip_unregister_exten_state_provider(&cpim_pidf_xml_provider);
+	pool_ref(-1);
+}




More information about the asterisk-commits mailing list