[asterisk-commits] kharwell: branch kharwell/pimp_sip_state r387626 - in /team/kharwell/pimp_sip...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri May 3 17:26:17 CDT 2013
Author: kharwell
Date: Fri May 3 17:23:07 2013
New Revision: 387626
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387626
Log:
update preparations for inclusion of dependent extension state providers
Added:
team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h (with props)
team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in (with props)
Modified:
team/kharwell/pimp_sip_state/res/res_sip_exten_state.c
Added: 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=auto&rev=387626
==============================================================================
--- team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h (added)
+++ team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h Fri May 3 17:23:07 2013
@@ -1,0 +1,66 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _RES_SIP_EXTEN_STATE_H
+#define _RES_SIP_EXTEN_STATE_H
+
+#include "asterisk/presencestate.h"
+
+struct ast_exten_state {
+ /*! The extension of the current state change */
+ const char *exten;
+ /*! The extension state of the change */
+ int exten_state;
+ /*! The presence state of the change */
+ enum ast_presence_state presence_state;
+ /*! Current device state information */
+ struct ao2_container *device_state;
+};
+
+/*!
+ * \brief Extension state notifier.
+ */
+struct ast_exten_state_notifier {
+ /*! The name of the event this notifier registers for */
+ const char *event_name;
+ /*! The type of body this notifier accepts */
+ const char *accept;
+
+ /*!
+ * \brief Create the body text of a NOTIFY request.
+ *
+ * Implementors use this to create body information within the given
+ * ast_str. That information is then added to the NOTIFY request.
+ */
+ void (*create_body)(struct ast_exten_state *data, struct ast_str **body_text);
+
+ /*! Next item in the list */
+ AST_LIST_ENTRY(ast_exten_state_notifier) next;
+};
+
+/*!
+ * \brief Register an extension state notifier.
+ */
+int ast_register_exten_state_notifier(struct ast_exten_state_notifier *obj);
+
+/*!
+ * \brief Unregister an extension state notifier.
+ */
+void ast_unregister_exten_state_notifier(struct ast_exten_state_notifier *obj);
+
+#endif
Propchange: team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: team/kharwell/pimp_sip_state/include/asterisk/res_sip_exten_state.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=387626&r1=387625&r2=387626
==============================================================================
--- team/kharwell/pimp_sip_state/res/res_sip_exten_state.c (original)
+++ team/kharwell/pimp_sip_state/res/res_sip_exten_state.c Fri May 3 17:23:07 2013
@@ -31,6 +31,7 @@
#include "asterisk/res_sip.h"
#include "asterisk/res_sip_pubsub.h"
+#include "asterisk/res_sip_exten_state.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/astobj2.h"
@@ -38,31 +39,9 @@
#include "asterisk/app.h"
#include "asterisk/pbx.h"
-/*!
- * \internal
- * \brief Extension state notifier.
- */
-struct exten_state_notifier {
- /*! The name of the event this notifier registers for */
- const char *event_name;
- /*! The type of body this notifier accepts */
- const char *accept;
-
- /*!
- * \brief Create the body text of a NOTIFY request.
- *
- * Implementors use this to create body information within the given
- * ast_str. That information is then added to the NOTIFY request.
- */
- void (*create_body)(struct ao2_container *info, struct ast_str *body_text);
-
- /*! Next item in the list */
- AST_LIST_ENTRY(exten_state_notifier) next;
-};
-
-AST_RWLIST_HEAD_STATIC(notifiers, exten_state_notifier);
-
-static int register_exten_state_notifier(struct exten_state_notifier *obj)
+AST_RWLIST_HEAD_STATIC(notifiers, ast_exten_state_notifier);
+
+int ast_register_exten_state_notifier(struct ast_exten_state_notifier *obj)
{
SCOPED_LOCK(lock, ¬ifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
AST_LIST_INSERT_TAIL(¬ifiers, obj, next);
@@ -70,9 +49,9 @@
return 0;
}
-static void unregister_exten_state_notifier(struct exten_state_notifier *obj)
-{
- struct exten_state_notifier *i;
+void ast_unregister_exten_state_notifier(struct ast_exten_state_notifier *obj)
+{
+ struct ast_exten_state_notifier *i;
SCOPED_LOCK(lock, ¬ifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(¬ifiers, i, next) {
if (i == obj) {
@@ -88,10 +67,10 @@
* \internal
* \brief Find a notifier based on the given accept type.
*/
-static struct exten_state_notifier *notifier_by_accept(const char *accept)
-{
- struct exten_state_notifier *res = NULL;
- struct exten_state_notifier *i;
+static struct ast_exten_state_notifier *notifier_by_accept(const char *accept)
+{
+ struct ast_exten_state_notifier *res = NULL;
+ struct ast_exten_state_notifier *i;
SCOPED_LOCK(lock, ¬ifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(¬ifiers, i, next) {
if (!strcmp(i->accept, accept)) {
@@ -110,13 +89,13 @@
* Attempts to locate accept headers in the given request data. If found
* tries to find a notifier for the accept type.
*/
-static struct exten_state_notifier *notifier_by_req(pjsip_rx_data *rdata)
+static struct ast_exten_state_notifier *notifier_by_req(pjsip_rx_data *rdata)
{
int i;
char type[50];
pjsip_accept_hdr *hdr = (pjsip_accept_hdr*)
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, NULL);
- struct exten_state_notifier *res;
+ struct ast_exten_state_notifier *res;
if (!hdr) {
ast_log(LOG_WARNING, "No Accept header found in subscribe\n");
@@ -162,14 +141,12 @@
/*! The SIP subscription */
struct ast_sip_subscription *sip_sub;
/*! The notify data creator */
- struct exten_state_notifier *notifier;
+ struct ast_exten_state_notifier *notifier;
/*! Context in which subscription looks for updates */
const char *context;
/*! Extension within the context to receive updates from */
char exten[AST_MAX_EXTENSION];
- /*! Last state information set during state change callback */
- struct ao2_container *state_info;
- /*! State when sending an serialized notify */
+ /*! pjsip state for NOTIFY request */
pjsip_evsub_state state;
};
@@ -247,8 +224,8 @@
* \internal
* \brief Create and send a NOTIFY request to the subscriber.
*/
-static void create_send_notify(struct state_sub *sub, pjsip_evsub_state state,
- const char *reason, struct ao2_container *info)
+static void create_send_notify(struct state_sub *ssub, const char *reason,
+ struct ast_exten_state *data)
{
RAII_VAR(struct ast_str *, body_text, ast_str_create(512), ast_free_ptr);
pj_str_t reason_str;
@@ -257,22 +234,22 @@
struct ast_sip_body body;
char type[50];
- if (!(body.subtype = strchr(sub->notifier->accept, '/'))) {
+ if (!(body.subtype = strchr(ssub->notifier->accept, '/'))) {
ast_log(LOG_WARNING, "Subtype not specified for notifier\n");
return;
}
- ast_copy_string(type, sub->notifier->accept,
- body.subtype - sub->notifier->accept);
+ ast_copy_string(type, ssub->notifier->accept,
+ body.subtype - ssub->notifier->accept);
body.type = type;
++body.subtype;
- if (!sub->notifier->create_body) {
+ if (!ssub->notifier->create_body) {
ast_log(LOG_WARNING, "Body handler not specified for notifier\n");
return;
}
- sub->notifier->create_body(info, body_text);
+ ssub->notifier->create_body(data, &body_text);
body.body_text = ast_str_buffer(body_text);
if (reason) {
@@ -280,7 +257,7 @@
reason_str_ptr = &reason_str;
}
- if (pjsip_evsub_notify(ast_sip_subscription_get_evsub(sub->sip_sub), state,
+ if (pjsip_evsub_notify(ast_sip_subscription_get_evsub(ssub->sip_sub), ssub->state,
NULL, reason_str_ptr, &tdata) != PJ_SUCCESS) {
ast_log(LOG_WARNING, "Unable to create NOTIFY request\n");
return;
@@ -292,7 +269,7 @@
return;
}
- if (ast_sip_subscription_send_request(sub->sip_sub, tdata) != PJ_SUCCESS) {
+ if (ast_sip_subscription_send_request(ssub->sip_sub, tdata) != PJ_SUCCESS) {
ast_log(LOG_WARNING, "Unable to send NOTIFY request\n");
pjsip_tx_data_dec_ref(tdata);
}
@@ -302,23 +279,42 @@
* \internal
* \brief Get device state information and send notification to the subscriber.
*/
-static void send_notify(struct state_sub *ssub, pjsip_evsub_state state, const char *reason)
+static void send_notify(struct state_sub *ssub, const char *reason)
{
RAII_VAR(struct ao2_container*, info, NULL, ao2_cleanup);
-
- if (ast_extension_state_extended(NULL, ssub->context, ssub->exten, &info)) {
- ast_log(LOG_WARNING, "Unable to get device info for extension %s\n", ssub->exten);
- return;
- }
-
- create_send_notify(ssub, state, reason, info);
-}
-
-static int serialized_notify(void *data)
-{
- struct state_sub *ssub = data;
- create_send_notify(ssub, ssub->state, NULL, ssub->state_info);
- ao2_ref(ssub, -1);
+ char *subtype = NULL, *message = NULL;
+
+ struct ast_exten_state sdata = {
+ .exten = ssub->exten,
+ .presence_state = ast_hint_presence_state(NULL, ssub->context,
+ ssub->exten, &subtype, &message),
+ };
+
+ if ((sdata.exten_state = ast_extension_state_extended(
+ NULL, ssub->context, ssub->exten, &info))) {
+
+ ast_log(LOG_WARNING, "Unable to get device info for extension %s\n",
+ ssub->exten);
+ return;
+ }
+
+ sdata.device_state = info;
+ create_send_notify(ssub, reason, &sdata);
+}
+
+struct serialized_userdata {
+ struct ast_exten_state *sdata;
+ struct state_sub *ssub;
+};
+
+static int serialized_notify(void *userdata)
+{
+ struct serialized_userdata *udata = userdata;
+ create_send_notify(udata->ssub, NULL, udata->sdata);
+
+ ao2_ref(udata->ssub, -1);
+ ao2_ref(udata->sdata->device_state, -1);
+ ast_free(udata->sdata);
return 0;
}
@@ -331,20 +327,28 @@
static int state_changed(char *context, char *exten,
struct ast_state_cb_info *info, void *data)
{
- struct state_sub *ssub = data;
+ struct serialized_userdata *udata = ast_malloc(sizeof(*udata));
+ struct ast_exten_state *sdata = ast_malloc(sizeof(*sdata));
+
+ udata->ssub = data;
+ ao2_ref(udata->ssub, +1);
+
+ sdata->exten = udata->ssub->exten;
+ sdata->exten_state = info->exten_state;
+ sdata->presence_state = info->presence_state;
+ sdata->device_state = info->device_state_info;
+ ao2_ref(sdata->device_state, +1);
+ udata->ssub->state = PJSIP_EVSUB_STATE_ACTIVE;
if ((info->exten_state == AST_EXTENSION_DEACTIVATED) ||
(info->exten_state == AST_EXTENSION_REMOVED)) {
- ssub->state = PJSIP_EVSUB_STATE_TERMINATED;
+ udata->ssub->state = PJSIP_EVSUB_STATE_TERMINATED;
ast_log(LOG_NOTICE, "Watcher for hint %s %s\n", exten, info->exten_state
== AST_EXTENSION_REMOVED ? "removed" : "deactivated");
}
- ao2_ref(ssub, +1);
- ssub->state = PJSIP_EVSUB_STATE_ACTIVE;
- ssub->state_info = info->device_state_info;
- ast_sip_push_task(ast_sip_subscription_get_serializer(ssub->sip_sub),
- serialized_notify, ssub);
+ ast_sip_push_task(ast_sip_subscription_get_serializer(udata->ssub->sip_sub),
+ serialized_notify, sdata);
return 0;
}
@@ -429,7 +433,8 @@
pjsip_evsub_accept(ast_sip_subscription_get_evsub(ssub->sip_sub),
rdata, 200, NULL);
- send_notify(ssub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
+ ssub->state = PJSIP_EVSUB_STATE_ACTIVE;
+ send_notify(ssub, NULL);
return ssub->sip_sub;
}
@@ -439,7 +444,8 @@
struct state_sub *ssub = from_datastore(sub);
if (ssub) {
- send_notify(ssub, PJSIP_EVSUB_STATE_ACTIVE, NULL);
+ ssub->state = PJSIP_EVSUB_STATE_ACTIVE;
+ send_notify(ssub, NULL);
}
}
@@ -452,7 +458,8 @@
}
ast_log(LOG_NOTICE, "Subscription for has timed out.\n");
- send_notify(ssub, PJSIP_EVSUB_STATE_TERMINATED, "timeout");
+ ssub->state = PJSIP_EVSUB_STATE_TERMINATED;
+ send_notify(ssub, "timeout");
}
static void subscription_terminated(struct ast_sip_subscription *sub,
@@ -465,7 +472,8 @@
}
ast_log(LOG_NOTICE, "Subscription has been terminated\n");
- send_notify(ssub, PJSIP_EVSUB_STATE_TERMINATED, NULL);
+ ssub->state = PJSIP_EVSUB_STATE_TERMINATED;
+ send_notify(ssub, NULL);
}
static void notify_response(struct ast_sip_subscription *sub, pjsip_rx_data *rdata)
@@ -577,7 +585,7 @@
*/
static void create_sub_handlers(void)
{
- struct exten_state_notifier *i;
+ struct ast_exten_state_notifier *i;
SCOPED_LOCK(lock, ¬ifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(¬ifiers, i, next) {
struct ast_sip_subscription_handler *handler =
@@ -641,7 +649,7 @@
/* register notifiers - for now they have to be specifically added here
because of a limitation in pjsip. if pjsip ever gets modified these
can be moved to their respective module files */
- register_exten_state_notifier(NULL);
+ ast_register_exten_state_notifier(NULL);
/* create the subscription handlers based upon the notifiers */
create_sub_handlers();
@@ -660,7 +668,7 @@
unregister_sub_handlers, NULL);
/* unregister notifiers here, again due to pjsip limitation */
- unregister_exten_state_notifier(NULL);
+ ast_unregister_exten_state_notifier(NULL);
ao2_cleanup(sub_handlers);
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=387626
==============================================================================
--- 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 Fri May 3 17:23:07 2013
@@ -1,0 +1,7 @@
+{
+ global:
+ LINKER_SYMBOL_PREFIXast_register_exten_notifier;
+ LINKER_SYMBOL_PREFIXast_unregister_exten_state_notifier;
+ 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 Revision
Propchange: team/kharwell/pimp_sip_state/res/res_sip_exten_state.exports.in
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list