[asterisk-commits] mmichelson: branch group/pimp_my_sip r379913 - in /team/group/pimp_my_sip: in...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 22 13:31:20 CST 2013


Author: mmichelson
Date: Tue Jan 22 13:31:16 2013
New Revision: 379913

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=379913
Log:
Handle inv_session state changes.

What this means is that any sort of incoming or outgoing
SIP message on a SIP session will pass through our hands, and
all session supplements will be visited.

In addition, this introduces a shortcut method for copying a
pj_str_t into a character buffer.


Modified:
    team/group/pimp_my_sip/include/asterisk/res_sip.h
    team/group/pimp_my_sip/res/res_sip.c
    team/group/pimp_my_sip/res/res_sip.exports.in
    team/group/pimp_my_sip/res/res_sip_session.c

Modified: team/group/pimp_my_sip/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/include/asterisk/res_sip.h?view=diff&rev=379913&r1=379912&r2=379913
==============================================================================
--- team/group/pimp_my_sip/include/asterisk/res_sip.h (original)
+++ team/group/pimp_my_sip/include/asterisk/res_sip.h Tue Jan 22 13:31:16 2013
@@ -579,4 +579,20 @@
  */
 int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text);
 
+/*!
+ * \brief Copy a pj_str_t into a standard character buffer.
+ *
+ * pj_str_t is not NULL-terminated. Any place that expects a NULL-
+ * terminated string needs to have the pj_str_t copied into a separate
+ * buffer.
+ *
+ * This method copies the pj_str_t contents into the destination buffer
+ * and NULL-terminates the buffer.
+ *
+ * \param dest The destination buffer
+ * \param src The pj_str_t to copy
+ * \param size The size of the destination buffer.
+ */
+void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size);
+
 #endif /* _RES_SIP_H */

Modified: team/group/pimp_my_sip/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip.c?view=diff&rev=379913&r1=379912&r2=379913
==============================================================================
--- team/group/pimp_my_sip/res/res_sip.c (original)
+++ team/group/pimp_my_sip/res/res_sip.c Tue Jan 22 13:31:16 2013
@@ -462,6 +462,13 @@
 	return ast_taskprocessor_push(work->queue, sip_task, task_data);
 }
 
+void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size)
+{
+	size_t chars_to_copy = MIN(size - 1, pj_strlen(src));
+	memcpy(dest, pj_strbuf(src), chars_to_copy);
+	dest[chars_to_copy] = '\0';
+}
+
 pj_caching_pool caching_pool;
 pj_pool_t *memory_pool;
 pj_thread_t *monitor_thread;

Modified: team/group/pimp_my_sip/res/res_sip.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip.exports.in?view=diff&rev=379913&r1=379912&r2=379913
==============================================================================
--- team/group/pimp_my_sip/res/res_sip.exports.in (original)
+++ team/group/pimp_my_sip/res/res_sip.exports.in Tue Jan 22 13:31:16 2013
@@ -22,6 +22,7 @@
 		LINKER_SYMBOL_PREFIXast_sip_append_body;
 		LINKER_SYMBOL_PREFIXast_sip_get_pjsip_endpoint;
 		LINKER_SYMBOL_PREFIXast_sip_endpoint_alloc;
+		LINKER_SYMBOL_PREFIXast_copy_pj_str;
 		LINKER_SYMBOL_PREFIXpj_*;
 		LINKER_SYMBOL_PREFIXpjsip_*;
 		LINKER_SYMBOL_PREFIXpjmedia_*;

Modified: team/group/pimp_my_sip/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip_session.c?view=diff&rev=379913&r1=379912&r2=379913
==============================================================================
--- team/group/pimp_my_sip/res/res_sip_session.c (original)
+++ team/group/pimp_my_sip/res/res_sip_session.c Tue Jan 22 13:31:16 2013
@@ -144,14 +144,11 @@
 	for (i = 0; i < sdp->media_count; ++i) {
 		/* See if there are registered handlers for this media stream type */
 		char media[20];
-		size_t chars_to_copy;
 		struct ast_sip_session_sdp_handler *handler;
 		RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
 
 		/* We need a null-terminated version of the media string */
-		chars_to_copy = MIN(sizeof(media)-1, pj_strlen(&sdp->media[i]->desc.media));
-		memcpy(media, pj_strbuf(&sdp->media[i]->desc.media), chars_to_copy);
-		media[chars_to_copy] = '\0';
+		ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));
 
 		handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
 		if (!handler_list) {
@@ -517,15 +514,11 @@
 {
 	pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
 	pjsip_sip_uri *sip_ruri;
-	size_t chars_to_copy;
 	if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
 		return SIP_GET_DEST_UNSUPPORTED_URI;
 	}
 	sip_ruri = pjsip_uri_get_uri(ruri);
-	/* This sucks. If there's a better way to do this, please inform me. */
-	chars_to_copy = MIN(pj_strlen(&sip_ruri->user), sizeof(session->exten) - 1);
-	memcpy(session->exten, pj_strbuf(&sip_ruri->user), chars_to_copy);
-	session->exten[chars_to_copy] = '\0';
+	ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
 	if (ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
 		return SIP_GET_DEST_EXTEN_FOUND;
 	}
@@ -565,6 +558,101 @@
 		return NULL;
 	}
 	return inv_session;
+}
+
+static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	char method[16];
+	struct pjsip_request_line req = rdata->msg_info.msg->line.req;
+	pj_str_t *pj_method = &req.method.name;
+
+	ast_copy_pj_str(method, pj_method, sizeof(method));
+
+	ast_debug(3, "Method is %s\n", method);
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (supplement->incoming_request && (
+				!supplement->method || !strcmp(supplement->method, method))) {
+			supplement->incoming_request(session, rdata);
+		}
+	}
+}
+
+static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_status_line status = rdata->msg_info.msg->line.status;
+
+	ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
+			pj_strbuf(&status.reason));
+
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		/* XXX Not sure how to get the method from a response.
+		 * For now, just call supplements on all responses, no
+		 * matter the method. This is less than ideal
+		 */
+		if (supplement->outgoing_request) {
+			supplement->incoming_response(session, rdata);
+		}
+	}
+}
+
+static void handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	ast_debug(3, "Received %s\n", rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ?
+			"request" : "response");
+	if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
+		handle_incoming_request(session, rdata);
+	} else {
+		handle_incoming_response(session, rdata);
+	}
+}
+
+static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	char method[16];
+	struct pjsip_request_line req = tdata->msg->line.req;
+	pj_str_t *pj_method = &req.method.name;
+
+	ast_copy_pj_str(method, pj_method, sizeof(method));
+
+	ast_debug(3, "Method is %s\n", method);
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		if (supplement->outgoing_request && 
+				(!supplement->method || !strcmp(supplement->method, method))) {
+			supplement->outgoing_request(session, tdata);
+		}
+	}
+}
+
+static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_sip_session_supplement *supplement;
+	struct pjsip_status_line status = tdata->msg->line.status;
+	ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
+			pj_strbuf(&status.reason));
+
+	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
+		/* XXX Not sure how to get the method from a response.
+		 * For now, just call supplements on all responses, no
+		 * matter the method. This is less than ideal
+		 */
+		if (supplement->outgoing_response) {
+			supplement->outgoing_response(session, tdata);
+		}
+	}
+}
+
+static void handle_outgoing(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	ast_debug(3, "Sending %s\n", tdata->msg->type == PJSIP_REQUEST_MSG ?
+			"request" : "response");
+	if (tdata->msg->type == PJSIP_REQUEST_MSG) {
+		handle_outgoing_request(session, tdata);
+	} else {
+		handle_outgoing_response(session, tdata);
+	}
 }
 
 static void handle_new_invite(pjsip_rx_data *rdata)
@@ -580,7 +668,6 @@
 	pjsip_inv_session *inv_session = NULL;
 	struct ast_sip_endpoint *endpoint = NULL;
 	struct ast_sip_session *session = NULL;
-	struct ast_sip_session_supplement *supplement = NULL;
 	pjsip_rdata_sdp_info *sdp_info;
 	pjmedia_sdp_session *local = NULL;
 
@@ -675,11 +762,7 @@
 		pjsip_inv_set_local_sdp(inv_session, local);
 	}
 
-	AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
-		if (!supplement->method || !strcmp(supplement->method, "INVITE")) {
-			supplement->incoming_request(session, rdata);
-		}
-	}
+	handle_incoming_request(session, rdata);
 }
 
 /*!
@@ -730,35 +813,34 @@
 
 static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
 {
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
 	ast_debug(3, "on_state_changed callback called. Event dump to follow\n");
 	ast_debug(3, "inv state is %s, event type is %s\n", pjsip_inv_state_name(inv->state), pjsip_event_str(e->type));
 	switch(e->type) {
 	case PJSIP_EVENT_TX_MSG:
-		ast_debug(3, "Sending %s\n", e->body.tx_msg.tdata->msg->type == PJSIP_REQUEST_MSG ? "request" : "response");
-		if (e->body.tx_msg.tdata->msg->type == PJSIP_REQUEST_MSG) {
-			struct pjsip_request_line req = e->body.tx_msg.tdata->msg->line.req;
-			ast_debug(3, "Method is %.*s\n", (int) pj_strlen(&req.method.name),
-					pj_strbuf(&req.method.name));
-		} else {
-			struct pjsip_status_line status = e->body.tx_msg.tdata->msg->line.status;
-			ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
-					pj_strbuf(&status.reason));
-		}
+		handle_outgoing(session, e->body.tx_msg.tdata);
 		break;
 	case PJSIP_EVENT_RX_MSG:
-		ast_debug(3, "Received %s\n", e->body.rx_msg.rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ? "request" : "response");
-		if (e->body.rx_msg.rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
-			struct pjsip_request_line req = e->body.rx_msg.rdata->msg_info.msg->line.req;
-			ast_debug(3, "Method is %.*s\n", (int) pj_strlen(&req.method.name),
-					pj_strbuf(&req.method.name));
-		} else {
-			struct pjsip_status_line status = e->body.rx_msg.rdata->msg_info.msg->line.status;
-			ast_debug(3, "Response is %d %.*s\n", status.code, (int) pj_strlen(&status.reason),
-					pj_strbuf(&status.reason));
-		}
+		handle_incoming(session, e->body.rx_msg.rdata);
 		break;
 	case PJSIP_EVENT_TSX_STATE:
 		ast_debug(3, "Source of transaction state change is %s\n", pjsip_event_str(e->body.tsx_state.type));
+		/* Transaction state changes are prompted by some other underlying event. */
+		switch(e->body.tsx_state.type) {
+		case PJSIP_EVENT_TX_MSG:
+			handle_outgoing(session, e->body.tsx_state.src.tdata);
+			break;
+		case PJSIP_EVENT_RX_MSG:
+			handle_incoming(session, e->body.tsx_state.src.rdata);
+			break;
+		case PJSIP_EVENT_TRANSPORT_ERROR:
+		case PJSIP_EVENT_TIMER:
+		case PJSIP_EVENT_USER:
+		case PJSIP_EVENT_UNKNOWN:
+		case PJSIP_EVENT_TSX_STATE:
+			/* Inception? */
+			break;
+		}
 		break;
 	case PJSIP_EVENT_TRANSPORT_ERROR:
 	case PJSIP_EVENT_TIMER:




More information about the asterisk-commits mailing list