[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, &notifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
 	AST_LIST_INSERT_TAIL(&notifiers, 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, &notifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&notifiers, 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, &notifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&notifiers, 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, &notifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&notifiers, 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