[asterisk-commits] mmichelson: branch mmichelson/pub_sub r384608 - in /team/mmichelson/pub_sub: ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 2 19:11:54 CDT 2013


Author: mmichelson
Date: Tue Apr  2 19:11:50 2013
New Revision: 384608

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384608
Log:
Add initial support for handling incoming SUBSCRIBEs.


Modified:
    team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h
    team/mmichelson/pub_sub/res/res_sip_pubsub.c

Modified: team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h?view=diff&rev=384608&r1=384607&r2=384608
==============================================================================
--- team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h (original)
+++ team/mmichelson/pub_sub/include/asterisk/res_sip_pubsub.h Tue Apr  2 19:11:50 2013
@@ -44,7 +44,7 @@
     AST_SIP_NOTIFIER,
 };
 
-#define AST_SIP_MAX_ACCEPT 10
+#define AST_SIP_MAX_ACCEPT 32
 
 struct ast_sip_subscription_handler {
     /*! The name of the event this handler deals with */

Modified: team/mmichelson/pub_sub/res/res_sip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pub_sub/res/res_sip_pubsub.c?view=diff&rev=384608&r1=384607&r2=384608
==============================================================================
--- team/mmichelson/pub_sub/res/res_sip_pubsub.c (original)
+++ team/mmichelson/pub_sub/res/res_sip_pubsub.c Tue Apr  2 19:11:50 2013
@@ -22,7 +22,7 @@
 #include "asterisk.h"
 
 #include <pjsip.h>
-#include <pjsip_ua.h>
+#include <pjsip_simple.h>
 #include <pjlib.h>
 
 #include "asterisk/res_sip_pubsub.h"
@@ -34,10 +34,19 @@
 #include "asterisk/taskprocessor.h"
 #include "asterisk/res_sip.h"
 
+static pj_bool_t sub_on_rx_request(pjsip_rx_data *rdata);
+
+static struct pjsip_module sub_module = {
+	.name = { "PubSub Module", 13 },
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION,
+	.on_rx_request = sub_on_rx_request,
+};
+
 struct ast_sip_subscription {
 	struct ao2_container *datastores;
 	struct ast_sip_endpoint *endpoint;
 	struct ast_taskprocessor *serializer;
+	const struct ast_sip_subscription_handler *handler;
 	pjsip_evsub *evsub;
 };
 
@@ -92,6 +101,7 @@
 	}
 	ao2_ref(endpoint, +1);
 	sub->endpoint = endpoint;
+	sub->handler = handler;
 	return sub;
 }
  
@@ -216,8 +226,93 @@
 	AST_RWLIST_TRAVERSE_SAFE_END;
 }
 
+static struct ast_sip_subscription_handler *find_handler(const char *event, char accept[][AST_SIP_MAX_ACCEPT], size_t num_accept)
+{
+	struct ast_sip_subscription_handler *iter;
+	int match = 0;
+	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+	AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
+		int i;
+		int j;
+		if (strcmp(event, iter->event_name)) {
+			continue;
+		}
+		for (i = 0; i < num_accept; ++i) {
+			for (j = 0; j < num_accept; ++j) {
+				if (ast_strlen_zero(iter->accept[i])) {
+					break;
+				}
+				if (!strcmp(accept[j], iter->accept[i])) {
+					match = 1;
+					break;
+				}
+			}
+			if (match) {
+				break;
+			}
+		}
+		if (match) {
+			break;
+		}
+	}
+
+	return iter;
+}
+
+static pj_bool_t sub_on_rx_request(pjsip_rx_data *rdata)
+{
+	static const pj_str_t event_name = { "Event", 5 };
+	char event[32];
+	char accept[64][AST_SIP_MAX_ACCEPT];
+	pjsip_accept_hdr *accept_header;
+	pjsip_event_hdr *event_header;
+	struct ast_sip_subscription_handler *handler;
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	struct ast_sip_subscription *sub;
+	int i;
+	if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method())) {
+		return PJ_FALSE;
+	}
+
+	endpoint = ast_pjsip_rdata_get_endpoint(rdata);
+	ast_assert(endpoint != NULL);
+
+	event_header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &event_name, rdata->msg_info.msg->hdr.next);
+	if (!event_header) {
+		ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Event header\n");
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	accept_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_ACCEPT, rdata->msg_info.msg->hdr.next);
+	if (!accept_header) {
+		ast_log(LOG_WARNING, "Incoming SUBSCRIBE request with no Accept header\n");
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 400, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+
+	ast_copy_pj_str(event, &event_header->event_type, sizeof(event));
+	for (i = 0; i < accept_header->count; ++i) {
+		ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i]));
+	}
+
+	handler = find_handler(event, accept, accept_header->count);
+	if (!handler) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 489, NULL, NULL, NULL);
+		return PJ_TRUE;
+	}
+	sub = handler->new_subscribe(endpoint, rdata);
+	if (!sub) {
+		pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
+	}
+	return PJ_TRUE;
+}
+
 static int load_module(void)
 {
+	if (ast_sip_register_service(&sub_module)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
 




More information about the asterisk-commits mailing list