[asterisk-commits] kharwell: branch kharwell/pimp_sip_state r389616 - in /team/kharwell/pimp_sip...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 23 15:36:44 CDT 2013
Author: kharwell
Date: Thu May 23 15:36:40 2013
New Revision: 389616
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389616
Log:
review issues addressed - removed horrible module reg workaround, but still need to merge in fix for that from pub/sub
Added:
team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in (with props)
team/kharwell/pimp_sip_state/res/res_sip_pidf.c
- copied, changed from r389484, team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c
Removed:
team/kharwell/pimp_sip_state/res/res_sip_providers/
Modified:
team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
team/kharwell/pimp_sip_state/res/Makefile
team/kharwell/pimp_sip_state/res/res_sip_exten_state.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=389616&r1=389615&r2=389616
==============================================================================
--- 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 Thu May 23 15:36:40 2013
@@ -50,8 +50,10 @@
const char *type;
/*! Subtype of the body, ex: "pidf+xml" */
const char *subtype;
- /*! Type/Subtype appended together - set internally */
- char body_type[50];
+ /*! Type/Subtype together - ex: application/pidf+xml */
+ const char *body_type;
+ /*! Subscription handler to be used and associated with provider */
+ struct ast_sip_subscription_handler *handler;
/*!
* \brief Create the body text of a NOTIFY request.
@@ -63,6 +65,8 @@
* \param local URI of the dialog's local party, e.g. 'from'
* \param remote URI of the dialog's remote party, e.g. 'to'
* \param body_text Out parameter used to populate the NOTIFY msg body
+ * \retval 0 Successfully created the body's text
+ * \retval -1 Failed to create the body's text
*/
int (*create_body)(struct ast_sip_exten_state_data *data, const char *local,
const char *remote, struct ast_str **body_text);
@@ -75,6 +79,8 @@
* \brief Registers an extension state provider.
*
* \param obj An extension state provider
+ * \retval 0 Successfully registered the extension state provider
+ * \retval -1 Failed to register the extension state provider
*/
int ast_sip_register_exten_state_provider(struct ast_sip_exten_state_provider *obj);
Modified: team/kharwell/pimp_sip_state/res/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/res/Makefile?view=diff&rev=389616&r1=389615&r2=389616
==============================================================================
--- team/kharwell/pimp_sip_state/res/Makefile (original)
+++ team/kharwell/pimp_sip_state/res/Makefile Thu May 23 15:36:40 2013
@@ -46,9 +46,6 @@
$(if $(filter res_sip,$(EMBEDDED_MODS)),modules.link,res_sip.so): $(subst .c,.o,$(wildcard res_sip/*.c))
$(subst .c,.o,$(wildcard res_sip/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_sip)
-$(if $(filter res_sip_providers,$(EMBEDDED_MODS)),modules.link,res_sip_exten_state.so): $(subst .c,.o,$(wildcard res_sip_providers/*.c))
-$(subst .c,.o,$(wildcard res_sip_providers/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_sip_providers)
-
$(if $(filter res_stasis,$(EMBEDDED_MODS)),modules.link,res_stasis.so): $(subst .c,.o,$(wildcard stasis/*.c))
$(subst .c,.o,$(wildcard stasis/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,res_stasis)
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=389616&r1=389615&r2=389616
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_exten_state.c (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_exten_state.c Thu May 23 15:36:40 2013
@@ -37,69 +37,22 @@
#include "asterisk/astobj2.h"
#include "asterisk/sorcery.h"
#include "asterisk/app.h"
-#include "res_sip_providers/include/res_sip_providers.h"
#define BODY_SIZE 1024
-#define BODY_TYPE_SIZE 50
#define EVENT_TYPE_SIZE 50
AST_RWLIST_HEAD_STATIC(providers, ast_sip_exten_state_provider);
-int ast_sip_register_exten_state_provider(struct ast_sip_exten_state_provider *obj)
-{
- SCOPED_LOCK(lock, &providers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
-
- if (ast_strlen_zero(obj->type)) {
- ast_log(LOG_WARNING, "Type not specified on provider for event %s\n",
- obj->event_name);
- return -1;
- }
-
- if (ast_strlen_zero(obj->subtype)) {
- ast_log(LOG_WARNING, "Subtype not specified on provider for event %s\n",
- obj->event_name);
- return -1;
- }
-
- if (!obj->create_body) {
- ast_log(LOG_WARNING, "Body handler not specified on provide for event %s\n",
- 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;
-}
-
-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);
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&providers, i, next) {
- if (i == obj) {
- AST_RWLIST_REMOVE_CURRENT(next);
- ast_module_unref(ast_module_info->self);
- break;
- }
- }
- AST_RWLIST_TRAVERSE_SAFE_END;
-}
-
-/*!
- * \internal
- * \brief Find a provider based on the given accept type.
- */
-static struct ast_sip_exten_state_provider *provider_by_accept(const char *accept)
+/*!
+ * \internal
+ * \brief Find a provider based on the given accept body type.
+ */
+static struct ast_sip_exten_state_provider *provider_by_type(const char *type)
{
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) {
- if (!strcmp(i->body_type, accept)) {
+ if (!strcmp(i->body_type, type)) {
return i;
}
}
@@ -109,55 +62,21 @@
/*!
* \internal
- * \brief Find a provider based on a given message body's type/subtype.
- *
- * Attempts to locate accept headers in the given request data. If found
- * tries to find a provider for the accept type.
- */
-static struct ast_sip_exten_state_provider *provider_by_req(pjsip_rx_data *rdata)
+ * \brief Find a provider based on the given accept body types.
+ */
+static struct ast_sip_exten_state_provider *provider_by_types(const char *event_name,
+ char **types, int count)
{
int i;
- pjsip_accept_hdr *hdr = (pjsip_accept_hdr*)
- pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
-
- if (!hdr) {
- ast_log(LOG_WARNING, "No Accept header found in subscribe\n");
- return NULL;
- }
-
- for (i = 0; i < hdr->count; ++i) {
- struct ast_sip_exten_state_provider *res;
- char type[BODY_TYPE_SIZE];
-
- ast_copy_pj_str(type, &hdr->values[i], sizeof(type));
- if ((res = provider_by_accept(type))) {
+ struct ast_sip_exten_state_provider *res;
+ for (i = 0; i < count; ++i) {
+ if ((res = provider_by_type(types[i])) &&
+ !strcmp(event_name, res->event_name)) {
return res;
}
}
return NULL;
}
-
-static int sub_handler_hash(const void *obj, int flags)
-{
- const struct ast_sip_subscription_handler *handler = obj;
- const char *event_name = obj;
-
- return ast_str_hash(flags & OBJ_KEY ? event_name : handler->event_name);
-}
-
-static int sub_handler_cmp(void *obj, void *arg, int flags)
-{
- struct ast_sip_subscription_handler *handler1 = obj;
- struct ast_sip_subscription_handler *handler2 = arg;
- const char *event_name = arg;
-
- return !strcmp(handler1->event_name, flags & OBJ_KEY ?
- event_name : handler2->event_name) ? CMP_MATCH | CMP_STOP : 0;
-}
-
-#define SUB_HANDLER_BUCKETS 5
-
-static struct ao2_container *sub_handlers;
/*!
* \brief A subscription for extension state
@@ -171,8 +90,12 @@
int id;
/*! The SIP subscription */
struct ast_sip_subscription *sip_sub;
- /*! The notify data creator */
- struct ast_sip_exten_state_provider *provider;
+ /*! The name of the event the subscribed to */
+ char event_name[EVENT_TYPE_SIZE];
+ /*! The number of body types */
+ int body_types_count;
+ /*! The subscription body types */
+ char **body_types;
/*! Context in which subscription looks for updates */
char context[AST_MAX_CONTEXT];
/*! Extension within the context to receive updates from */
@@ -184,32 +107,45 @@
static void exten_state_subscription_destructor(void *obj)
{
struct exten_state_subscription *sub = obj;
+ int i;
+
+ for (i = 0; i < sub->body_types_count; ++i) {
+ ast_free(sub->body_types[i]);
+ }
+
+ ast_free(sub->body_types);
ao2_cleanup(sub->sip_sub);
}
/*!
* \internal
- * \brief Find a subscription handler based on a given message's event type.
- *
- * Attempts to locate an event header in the given request data. If found
- * tries to find a subscription handler for the event type.
- */
-static struct ast_sip_subscription_handler *sub_handler_by_req(pjsip_rx_data *rdata)
-{
- char type[EVENT_TYPE_SIZE];
- static const pj_str_t event_name = { "Event", 5 };
- pjsip_event_hdr *hdr = (pjsip_event_hdr*)
- pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &event_name, NULL);
-
- if (!hdr) {
- ast_log(LOG_WARNING, "No Event header found in subscribe\n");
- return NULL;
- }
-
- ast_copy_pj_str(type, &hdr->event_type, sizeof(type));
-
- return ao2_find(sub_handlers, type, OBJ_KEY | OBJ_NOLOCK);
-}
+ * \brief Copies the body types the message wishes to subscribe to.
+ */
+static void copy_body_types(pjsip_rx_data *rdata,
+ struct exten_state_subscription *exten_state_sub)
+{
+ int i;
+ pjsip_accept_hdr *hdr = (pjsip_accept_hdr*)
+ pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
+
+ exten_state_sub->body_types_count = hdr->count;
+ exten_state_sub->body_types = ast_malloc(hdr->count * sizeof(char*));
+
+ for (i = 0; i < hdr->count; ++i) {
+ exten_state_sub->body_types[i] =
+ ast_malloc(hdr->values[i].slen * sizeof(char*) + 1);
+
+ ast_copy_string(exten_state_sub->body_types[i],
+ pj_strbuf(&hdr->values[i]), hdr->values[i].slen + 1);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Initialize the last extension state to something outside
+ * its usual states.
+ */
+#define INITIAL_LAST_EXTEN_STATE -3
/*!
* \internal
@@ -221,7 +157,11 @@
static struct exten_state_subscription *exten_state_subscription_alloc(
struct ast_sip_endpoint *endpoint, enum ast_sip_subscription_role role, pjsip_rx_data *rdata)
{
- struct ast_sip_subscription_handler *handler;
+ static const pj_str_t event_name = { "Event", 5 };
+ pjsip_event_hdr *hdr = (pjsip_event_hdr*)pjsip_msg_find_hdr_by_name(
+ rdata->msg_info.msg, &event_name, NULL);
+
+ struct ast_sip_exten_state_provider *provider;
RAII_VAR(struct exten_state_subscription *, exten_state_sub,
ao2_alloc(sizeof(*exten_state_sub), exten_state_subscription_destructor), ao2_cleanup);
@@ -229,22 +169,25 @@
return NULL;
}
- if (!(handler = sub_handler_by_req(rdata))) {
- ast_log(LOG_WARNING, "Handler not found for subscription event\n");
- return NULL;
- }
-
- if (!(exten_state_sub->provider = provider_by_req(rdata))) {
- ast_log(LOG_WARNING, "Unable to locate subscription handler provider\n");
- return NULL;
- }
-
- if (!(exten_state_sub->sip_sub = ast_sip_create_subscription(handler, role, endpoint, rdata))) {
+ ast_copy_pj_str(exten_state_sub->event_name, &hdr->event_type,
+ sizeof(exten_state_sub->event_name));
+
+ copy_body_types(rdata, exten_state_sub);
+ if (!(provider = provider_by_types(exten_state_sub->event_name,
+ exten_state_sub->body_types,
+ exten_state_sub->body_types_count))) {
+ ast_log(LOG_WARNING, "Unable to locate subscription handler\n");
+ return NULL;
+ }
+
+ if (!(exten_state_sub->sip_sub = ast_sip_create_subscription(
+ provider->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;
+
+ exten_state_sub->last_exten_state = INITIAL_LAST_EXTEN_STATE;
ao2_ref(exten_state_sub, +1);
return exten_state_sub;
@@ -262,17 +205,26 @@
const pj_str_t *reason_str_ptr = NULL;
pjsip_tx_data *tdata;
pjsip_dialog *dlg;
- char local[256], remote[256];
- struct ast_sip_body body = {
- .type = exten_state_sub->provider->type,
- .subtype = exten_state_sub->provider->subtype
- };
+ char local[PJSIP_MAX_URL_SIZE], remote[PJSIP_MAX_URL_SIZE];
+ struct ast_sip_body body;
+
+ struct ast_sip_exten_state_provider *provider = provider_by_types(
+ exten_state_sub->event_name, exten_state_sub->body_types,
+ exten_state_sub->body_types_count);
+
+ if (!provider) {
+ ast_log(LOG_ERROR, "Unable to locate provider for subscription\n");
+ return;
+ }
+
+ body.type = provider->type;
+ body.subtype = provider->subtype;
dlg = ast_sip_subscription_get_dlg(exten_state_sub->sip_sub);
ast_copy_pj_str(local, &dlg->local.info_str, sizeof(local));
ast_copy_pj_str(remote, &dlg->remote.info_str, sizeof(remote));
- if (exten_state_sub->provider->create_body(exten_state_data, local, remote, &body_text)) {
+ if (provider->create_body(exten_state_data, local, remote, &body_text)) {
return;
}
@@ -343,7 +295,8 @@
ao2_cleanup(task_data->exten_state_data.device_state_info);
}
-static struct notify_task_data *alloc_notify_task_data(struct exten_state_subscription *exten_state_sub)
+static struct notify_task_data *alloc_notify_task_data(char *exten, struct exten_state_subscription *exten_state_sub,
+ struct ast_state_cb_info *info)
{
struct notify_task_data *task_data =
ao2_alloc(sizeof(*task_data), notify_task_data_destructor);
@@ -355,43 +308,10 @@
task_data->evsub_state = PJSIP_EVSUB_STATE_ACTIVE;
task_data->exten_state_sub = exten_state_sub;
+ task_data->exten_state_sub->last_exten_state = info->exten_state;
ao2_ref(task_data->exten_state_sub, +1);
+
task_data->exten_state_data.exten = exten_state_sub->exten;
-
- return task_data;
-}
-
-static int notify_task(void *obj)
-{
- RAII_VAR(struct notify_task_data *, task_data, obj, ao2_cleanup);
-
- create_send_notify(task_data->exten_state_sub, task_data->evsub_state ==
- PJSIP_EVSUB_STATE_TERMINATED ? "noresource" : NULL,
- task_data->evsub_state, &task_data->exten_state_data);
- return 0;
-}
-
-/*!
- * \internal
- * \brief Callback for exten/device state changes.
- *
- * Upon state change, send the appropriate notification to the subscriber.
- */
-static int state_changed(char *context, char *exten,
- struct ast_state_cb_info *info, void *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;
- }
-
task_data->exten_state_data.exten_state = info->exten_state;
task_data->exten_state_data.presence_state = info->presence_state;
task_data->exten_state_data.device_state_info = info->device_state_info;
@@ -405,6 +325,39 @@
task_data->evsub_state = PJSIP_EVSUB_STATE_TERMINATED;
ast_log(LOG_WARNING, "Watcher for hint %s %s\n", exten, info->exten_state
== AST_EXTENSION_REMOVED ? "removed" : "deactivated");
+ }
+
+ return task_data;
+}
+
+static int notify_task(void *obj)
+{
+ RAII_VAR(struct notify_task_data *, task_data, obj, ao2_cleanup);
+
+ create_send_notify(task_data->exten_state_sub, task_data->evsub_state ==
+ PJSIP_EVSUB_STATE_TERMINATED ? "noresource" : NULL,
+ task_data->evsub_state, &task_data->exten_state_data);
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Callback for exten/device state changes.
+ *
+ * Upon state change, send the appropriate notification to the subscriber.
+ */
+static int state_changed(char *context, char *exten,
+ struct ast_state_cb_info *info, void *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;
+ }
+
+ if (!(task_data = alloc_notify_task_data(exten, exten_state_sub, info))) {
+ return -1;
}
/* safe to push this async since we copy the data from info and
@@ -417,6 +370,12 @@
return 0;
}
+static void state_changed_destroy(int id, void *data)
+{
+ struct exten_state_subscription *exten_state_sub = data;
+ ao2_cleanup(exten_state_sub);
+}
+
static struct ast_datastore_info ds_info = { };
static const char ds_name[] = "exten state datastore";
@@ -427,7 +386,7 @@
* Adds the exten_state_subscription wrapper object to a datastore so it can be retrieved
* later based upon its association with the ast_sip_subscription.
*/
-static int add_datastore(struct exten_state_subscription *sub)
+static int add_datastore(struct exten_state_subscription *exten_state_sub)
{
RAII_VAR(struct ast_datastore *, datastore,
ast_sip_subscription_alloc_datastore(&ds_info, ds_name), ao2_cleanup);
@@ -436,8 +395,9 @@
return -1;
}
- datastore->data = sub;
- ast_sip_subscription_add_datastore(sub->sip_sub, datastore);
+ datastore->data = exten_state_sub;
+ ast_sip_subscription_add_datastore(exten_state_sub->sip_sub, datastore);
+ ao2_ref(exten_state_sub, +1);
return 0;
}
@@ -459,10 +419,14 @@
{
struct exten_state_subscription *exten_state_sub = get_exten_state_sub(sub);
- if (exten_state_sub) {
- ast_extension_state_del(exten_state_sub->id, state_changed);
- ao2_cleanup(exten_state_sub);
- }
+ if (!exten_state_sub) {
+ return;
+ }
+
+ ast_extension_state_del(exten_state_sub->id, state_changed);
+ ast_sip_subscription_remove_datastore(exten_state_sub->sip_sub, ds_name);
+ /* remove data store reference */
+ ao2_cleanup(exten_state_sub);
}
static struct ast_sip_subscription *new_subscribe(struct ast_sip_endpoint *endpoint,
@@ -481,15 +445,19 @@
return NULL;
}
- strncpy(exten_state_sub->context, endpoint->context, AST_MAX_CONTEXT);
+ ast_copy_string(exten_state_sub->context, endpoint->context, sizeof(exten_state_sub->context));
ast_copy_pj_str(exten_state_sub->exten, &sip_uri->user, sizeof(exten_state_sub->exten));
- if ((exten_state_sub->id = ast_extension_state_add(exten_state_sub->context, exten_state_sub->exten,
- state_changed, exten_state_sub)) < 0) {
+ if ((exten_state_sub->id = ast_extension_state_add_destroy_extended(
+ exten_state_sub->context, exten_state_sub->exten,
+ state_changed, state_changed_destroy, exten_state_sub)) < 0) {
ast_log(LOG_WARNING, "Unable to subscribe extension %s\n",
exten_state_sub->exten);
return NULL;
}
+
+ /* bump the ref since ast_extension_state_add holds a reference */
+ ao2_ref(exten_state_sub, +1);
if (add_datastore(exten_state_sub)) {
ast_log(LOG_WARNING, "Unable to add to subscription datastore.\n");
@@ -503,8 +471,6 @@
}
send_notify(exten_state_sub, NULL, PJSIP_EVSUB_STATE_ACTIVE);
- /* bump the ref since ast_extension_state_add holds a reference */
- ao2_ref(exten_state_sub, +1);
return exten_state_sub->sip_sub;
}
@@ -513,9 +479,11 @@
{
struct exten_state_subscription *exten_state_sub = get_exten_state_sub(sub);
- if (exten_state_sub) {
- send_notify(exten_state_sub, NULL, PJSIP_EVSUB_STATE_ACTIVE);
- }
+ if (!exten_state_sub) {
+ return;
+ }
+
+ send_notify(exten_state_sub, NULL, PJSIP_EVSUB_STATE_ACTIVE);
}
static void subscription_timeout(struct ast_sip_subscription *sub)
@@ -545,54 +513,13 @@
/*!
* \internal
- * \brief Checks to see if the given value is in the given accept array.
- * If it isn't return the index to the next usable space in the array.
- */
-static int in_accept_or_index(const char *accept[], const char *value)
-{
- int i;
- /* search all items or until we find a null/empty element */
- for (i = 0; i < sizeof(accept) &&
- !ast_strlen_zero(accept[i]); ++i) {
- if (!strcmp(accept[i], value)) {
- return -1;
- }
- }
- /* return the first empty element in the array */
- return i;
-}
-
-/*!
- * \internal
- * \brief Add given accept to 'dest' if 'dest' does not already contain
- * the accept type.
- */
-static void add_accept(const char* dest[], const char* accept)
-{
- int i = in_accept_or_index(dest, accept);
-
- if (i < 0) {
- /* already in accept list */
- return;
- }
-
- if (i == sizeof(dest)) {
- ast_log(LOG_WARNING, "Subcription handler's accept values full\n");
- return;
- }
-
- dest[i] = accept;
-}
-
-/*!
- * \internal
- * \brief Create a subscription handler.
+ * \brief Create and register a subscription handler.
*
* Creates a subscription handler that can be registered with the pub/sub
* framework for the given event_name and accept value.
*/
-static struct ast_sip_subscription_handler *create_sub_handler(const char *event_name,
- const char *accept)
+static struct ast_sip_subscription_handler *create_and_register_handler(
+ const char *event_name, const char *accept)
{
struct ast_sip_subscription_handler *handler =
ao2_alloc(sizeof(*handler), NULL);
@@ -602,7 +529,7 @@
}
handler->event_name = event_name;
- add_accept(handler->accept, accept);
+ handler->accept[0] = accept;
handler->subscription_shutdown = subscription_shutdown;
handler->new_subscribe = new_subscribe;
@@ -610,125 +537,71 @@
handler->subscription_timeout = subscription_timeout;
handler->subscription_terminated = subscription_terminated;
- return handler;
-}
-
-/*!
- * \internal
- * \brief Create a collection of subscription handlers.
- *
- * Currently pjsip only allows one event_name to be registered for a given
- * list of body type/application (accept) values. This list of values
- * cannot be modified once a particular event_name has been registered.
- * This means all accept values must be specified before registering a
- * subcription handler for an event_name with the pub/sub framework.
- *
- * For every registered provider create, or re-use, a subscription handler
- * based upon the event_name. If a handler does not exist for a particular
- * event_name one will be created adding the accept value from a provider.
- * If a handler already exists for an event_name then if the accept value
- * has not been added to that handler it will be.
- */
-static void create_sub_handlers(void)
-{
- 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) {
- struct ast_sip_subscription_handler *handler =
- ao2_find(sub_handlers, i->event_name, OBJ_NOLOCK | OBJ_KEY);
-
- 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, 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, i->body_type))) {
- ao2_link(sub_handlers, handler);
- }
- }
- AST_RWLIST_TRAVERSE_SAFE_END;
-}
-
-/*!
- * \internal
- * \brief Register a subscription handlers with the pub/sub framework.
- */
-static int register_sub_handlers(void *obj, void *arg, int flags)
-{
- struct ast_sip_subscription_handler *handler = obj;
- int *count = arg;
-
if (ast_sip_register_subscription_handler(handler)) {
ast_log(LOG_WARNING, "Unable to register subscription handler %s\n",
handler->event_name);
- } else {
- /* if at least one handler registers we will
- declare load success*/
- (*count)++;
- }
+ }
+
+ return handler;
+}
+
+int ast_sip_register_exten_state_provider(struct ast_sip_exten_state_provider *obj)
+{
+ SCOPED_LOCK(lock, &providers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+ if (ast_strlen_zero(obj->type)) {
+ ast_log(LOG_WARNING, "Type not specified on provider for event %s\n",
+ obj->event_name);
+ return -1;
+ }
+
+ if (ast_strlen_zero(obj->subtype)) {
+ ast_log(LOG_WARNING, "Subtype not specified on provider for event %s\n",
+ obj->event_name);
+ return -1;
+ }
+
+ if (!obj->create_body) {
+ ast_log(LOG_WARNING, "Body handler not specified on provide for event %s\n",
+ obj->event_name);
+ return -1;
+ }
+
+ obj->handler = create_and_register_handler(obj->event_name, obj->body_type);
+
+ AST_RWLIST_INSERT_TAIL(&providers, obj, next);
+ ast_module_ref(ast_module_info->self);
+
return 0;
}
-/*!
- * \internal
- * \brief Unregister a subscription handler with the pub/sub framework.
- */
-static int unregister_sub_handlers(void *obj, void *arg, int flags)
-{
- ast_sip_unregister_subscription_handler(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);
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&providers, i, next) {
+ if (i == obj) {
+ ast_sip_unregister_subscription_handler(i->handler);
+ ao2_cleanup(i->handler);
+ AST_RWLIST_REMOVE_CURRENT(next);
+ ast_module_unref(ast_module_info->self);
+ break;
+ }
+ }
+ AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
+static int load_module(void)
+{
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
return 0;
}
-static int load_module(void)
-{
- int count = 0;
-
- if (!(sub_handlers = ao2_container_alloc(SUB_HANDLER_BUCKETS,
- sub_handler_hash, sub_handler_cmp))) {
- return AST_MODULE_LOAD_FAILURE;
- }
-
- /* register providers - for now they have to be specifically added here
- because pjsip requires a registered event type and all associated
- body types be done once (i.e. you can't register 'presence' with
- '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 */
- 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();
-
- /* register each subscription handler declaring success if
- at least one registers */
- ao2_callback(sub_handlers, OBJ_NODATA | OBJ_NOLOCK,
- register_sub_handlers, &count);
-
- return count ? AST_MODULE_LOAD_SUCCESS : AST_MODULE_LOAD_FAILURE;
-}
-
-static int unload_module(void)
-{
- ao2_callback(sub_handlers, OBJ_NODATA | OBJ_NOLOCK,
- unregister_sub_handlers, NULL);
-
- /* unregister providers here, again due to pjsip limitation mentioned above */
- ast_sip_unregister_pidf_xml_provider();
- ast_sip_unregister_xpidf_xml_provider();
- ast_sip_unregister_cpim_pidf_xml_provider();
-
- ao2_cleanup(sub_handlers);
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Extension State Notifications",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "SIP Extension State Notifications",
.load = load_module,
.unload = unload_module,
.load_pri = AST_MODPRI_CHANNEL_DEPEND,
Added: team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in?view=auto&rev=389616
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in (added)
+++ team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in Thu May 23 15:36:40 2013
@@ -1,0 +1,7 @@
+{
+ global:
+ LINKER_SYMBOL_PREFIXast_sip_register_exten_state_provider;
+ LINKER_SYMBOL_PREFIXast_sip_unregister_exten_state_provider;
+ local:
+ *;
+};
Propchange: team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied: team/kharwell/pimp_sip_state/res/res_sip_pidf.c (from r389484, 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_pidf.c?view=diff&rev=389616&p1=team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c&r1=389484&p2=team/kharwell/pimp_sip_state/res/res_sip_pidf.c&r2=389616
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_providers/res_sip_pidf.c (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_pidf.c Thu May 23 15:36:40 2013
@@ -30,10 +30,9 @@
#include <pjsip_simple.h>
#include <pjlib.h>
+#include "asterisk/module.h"
#include "asterisk/res_sip.h"
#include "asterisk/res_sip_exten_state.h"
-#include "include/res_sip_providers.h"
-
enum state {
NOTIFY_OPEN,
@@ -229,25 +228,17 @@
.event_name = "presence",
.type = "application",
.subtype = "pidf+xml",
+ .body_type = "application/pidf+xml",
.create_body = pidf_xml_create_body
};
-void ast_sip_register_pidf_xml_provider(void)
-{
- 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);
-}
-
static int xpidf_xml_create_body(struct ast_sip_exten_state_data *data, const char *local,
const char *remote, struct ast_str **body_text)
{
+ static pj_str_t STR_ADDR_PARAM = { ";user=ip", 8 };
pjxpidf_pres *pres;
pj_xml_attr *attr;
- pj_str_t name;
+ pj_str_t name, uri;
char *statestring = NULL, *pidfstate = NULL, *pidfnote = NULL;
int local_state, size;
@@ -267,8 +258,12 @@
pj_strdup2(pool, &attr->value, data->exten);
attr = find_node_attr(pool, pres, "address", "uri");
- pj_strdup2(pool, &attr->value, remote);
- pj_strcat2(&attr->value, ";user=ip");
+
+ uri.ptr = (char*) pj_pool_alloc(pool, strlen(remote) + STR_ADDR_PARAM.slen);
+ pj_strcpy2( &uri, remote);
+ pj_strcat( &uri, &STR_ADDR_PARAM);
+ pj_strdup(pool, &attr->value, &uri);
+
create_attr(pool, pj_xml_find_node(pres, pj_cstr(&name, "address")),
"priority", "0.80000");
@@ -298,32 +293,49 @@
.event_name = "presence",
.type = "application",
.subtype = "xpidf+xml",
+ .body_type = "application/xpidf+xml",
.create_body = xpidf_xml_create_body
};
-
-void ast_sip_register_xpidf_xml_provider(void)
-{
- 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);
-}
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
+ .body_type = "application/cpim-pidf+xml",
+ .create_body = xpidf_xml_create_body,
};
-void ast_sip_register_cpim_pidf_xml_provider(void)
-{
- ast_sip_register_exten_state_provider(&cpim_pidf_xml_provider);
-}
-
-void ast_sip_unregister_cpim_pidf_xml_provider(void)
+static int load_module(void)
+{
+ if (ast_sip_register_exten_state_provider(&pidf_xml_provider)) {
+ ast_log(LOG_WARNING, "Unable to load provider event_name=%s, body_type=%s",
+ pidf_xml_provider.event_name, pidf_xml_provider.body_type);
+ }
+
+ if (ast_sip_register_exten_state_provider(&xpidf_xml_provider)) {
+ ast_log(LOG_WARNING, "Unable to load provider event_name=%s, body_type=%s",
+ xpidf_xml_provider.event_name, xpidf_xml_provider.body_type);
+ }
+
+ if (ast_sip_register_exten_state_provider(&cpim_pidf_xml_provider)) {
+ ast_log(LOG_WARNING, "Unable to load provider event_name=%s, body_type=%s",
+ cpim_pidf_xml_provider.event_name, cpim_pidf_xml_provider.body_type);
+ }
+
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
{
ast_sip_unregister_exten_state_provider(&cpim_pidf_xml_provider);
-}
+ ast_sip_unregister_exten_state_provider(&xpidf_xml_provider);
+ ast_sip_unregister_exten_state_provider(&pidf_xml_provider);
+
+ return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Extension State PIDF Provider",
+ .load = load_module,
+ .unload = unload_module,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
More information about the asterisk-commits
mailing list