[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(¬e, 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