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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 14 14:11:52 CST 2013


Author: mmichelson
Date: Mon Jan 14 14:11:48 2013
New Revision: 379061

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=379061
Log:
Get SDP handler registration and unregistration filled out.

I had to unconstify some arguments because there's no way to
create a linked list of const objects.

I also added an id field to SDP handlers for comparison purposes.
It can also be useful for debuggin statements.


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

Modified: team/group/pimp_my_sip/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/include/asterisk/res_sip_session.h?view=diff&rev=379061&r1=379060&r2=379061
==============================================================================
--- team/group/pimp_my_sip/include/asterisk/res_sip_session.h (original)
+++ team/group/pimp_my_sip/include/asterisk/res_sip_session.h Mon Jan 14 14:11:48 2013
@@ -18,6 +18,8 @@
 
 #ifndef _RES_SIP_SESSION_H
 #define _RES_SIP_SESSION_H
+
+#include "asterisk/linkedlists.h"
 
 /* Forward declarations */
 struct ast_sip_endpoint;
@@ -42,6 +44,8 @@
     struct pjsip_inv_session *inv_session;
     /* The Asterisk channel associated with the session */
     struct ast_channel *channel;
+	/* Registered session supplements */
+	AST_LIST_HEAD(, ast_sip_session_supplement) supplements;
     /* Datastores added to the session by supplements to the session */
 	struct ao2_container *datastores;
 };
@@ -71,6 +75,8 @@
     void (*outgoing_request)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
     /*! Called on an outgoing SIP response */
     void (*outgoing_response)(struct ast_sip_session *session, struct pjsip_tx_data *tdata);
+	/*! Next item in the list */
+	AST_LIST_ENTRY(ast_sip_session_supplement) next;
 };
 
 /*!
@@ -80,6 +86,8 @@
  * responsible party for specific types of SDP streams.
  */
 struct ast_sip_session_sdp_handler {
+	/*! An identifier for this handler */
+	const char *id;
     /*!
      * \brief Set session details based on a stream in an incoming SDP offer or answer
      * \param session The session for which the media is being negotiated
@@ -98,14 +106,16 @@
      * \retval >0 The handler has a stream to be added to the SDP. No further handler of this stream type will be called.
      */
     int (*create_outgoing_sdp_stream)(struct ast_sip_session *session, struct pjmedia_sdp_session *sdp);
+	/*! Next item int he list. */
+	AST_LIST_ENTRY(ast_sip_session_sdp_handler) next;
 };
 
 /*!
  * \brief Register an SDP handler
  *
- * An SDP handler is responsible for parsing incoming SDPs and ensuring that
+ * An SDP handler is responsible for parsing incoming SDP streams and ensuring that
  * Asterisk can cope with the contents. Similarly, the SDP handler will be
- * responsible for constructing outgoing SDPs.
+ * responsible for constructing outgoing SDP streams.
  *
  * Multiple handlers for the same stream type may be registered. They will be
  * visited in the order they were registered. Handlers will be visited for each
@@ -116,14 +126,15 @@
  * \retval 0 Success
  * \retval -1 Failure
  */
-int ast_sip_session_register_sdp_handler(const struct ast_sip_session_sdp_handler *handler, const char *stream_type);
+int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type);
 
 /*!
  * \brief Unregister an SDP handler
  *
  * \param handler The SDP handler to unregister
- */
-void ast_sip_session_unregister_sdp_handler(const struct ast_sip_session_sdp_handler *handler);
+ * \param stream_type Stream type for which the SDP handler was registered
+ */
+void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type);
 
 /*!
  * \brief Register a supplement to SIP session processing

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=379061&r1=379060&r2=379061
==============================================================================
--- team/group/pimp_my_sip/res/res_sip_session.c (original)
+++ team/group/pimp_my_sip/res/res_sip_session.c Mon Jan 14 14:11:48 2013
@@ -29,16 +29,96 @@
 #include "asterisk/module.h"
 #include "asterisk/logger.h"
 #include "asterisk/res_sip.h"
-
-int ast_sip_session_register_sdp_handler(const struct ast_sip_session_sdp_handler *handler, const char *stream_type)
-{
-	/* XXX STUB */
-	return 0;
-}
-
-void ast_sip_session_unregister_sdp_handler(const struct ast_sip_session_sdp_handler *handler)
-{
-	/* XXX STUB */
+#include "asterisk/astobj2.h"
+#include "asterisk/lock.h"
+
+#define SDP_HANDLER_BUCKETS 11
+/*!
+ * \brief Registered SDP stream handlers
+ *
+ * This container is keyed on stream types. Each
+ * object in the container is a linked list of
+ * handlers for the stream type.
+ */
+static struct ao2_container *sdp_handlers;
+
+/*!
+ * These are the objects in the sdp_handlers container
+ */
+struct sdp_handler_list {
+	/* The list of handlers to visit */
+	AST_LIST_HEAD_NOLOCK(, ast_sip_session_sdp_handler) list;
+	/* The handlers in this list handle streams of this type */
+	char stream_type[1];
+};
+
+static int sdp_handler_list_hash(const void *obj, int flags)
+{
+	const struct sdp_handler_list *handler_list = obj;
+	const char *stream_type = flags & OBJ_KEY ? handler_list->stream_type : obj;
+
+	return ast_str_hash(stream_type);
+}
+
+static int sdp_handler_list_cmp(void *obj, void *arg, int flags)
+{
+	struct sdp_handler_list *handler_list1 = obj;
+	struct sdp_handler_list *handler_list2 = obj;
+	const char *stream_type2 = flags & OBJ_KEY ? handler_list2->stream_type : arg;
+
+	return strcmp(handler_list1->stream_type, stream_type2) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
+{
+	RAII_VAR(struct sdp_handler_list *, handler_list,
+			ao2_find(sdp_handlers, stream_type, OBJ_KEY), ao2_cleanup);
+	SCOPED_AO2LOCK(lock, sdp_handlers);
+
+	if (handler_list) {
+		/* Already have a handler of this stream type. Just add this to the end of the list */
+		AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
+		return 0;
+	}
+
+	/* No stream of this type has been registered yet, so we need to create a new list */
+	handler_list = ao2_alloc(sizeof(*handler_list) + strlen(stream_type), NULL);
+	if (!handler_list) {
+		return -1;
+	}
+	/* Safe use of strcpy */
+	strcpy(handler_list->stream_type, stream_type);
+	AST_LIST_HEAD_INIT_NOLOCK(&handler_list->list);
+	AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
+	if (!ao2_link(sdp_handlers, handler_list)) {
+		return -1;
+	}
+	return 0;
+}
+
+static int remove_handler(void *obj, void *arg, void *data, int flags)
+{
+	struct sdp_handler_list *handler_list = obj;
+	struct ast_sip_session_sdp_handler *handler = data;
+	struct ast_sip_session_sdp_handler *iter;
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&handler_list->list, iter, next) {
+		if (!strcmp(iter->id, handler->id)) {
+			AST_LIST_REMOVE_CURRENT(next);
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
+	if (AST_LIST_EMPTY(&handler_list->list)) {
+		return CMP_MATCH;
+	} else {
+		return CMP_STOP;
+	}
+}
+
+void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
+{
+	ao2_callback_data(sdp_handlers, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, remove_handler, (void *)stream_type, handler);
 }
 
 int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement)
@@ -188,7 +268,13 @@
 
 static int load_module(void)
 {
-	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
+	pjsip_endpoint *endpt;
+	sdp_handlers = ao2_container_alloc(SDP_HANDLER_BUCKETS,
+			sdp_handler_list_hash, sdp_handler_list_cmp);
+	if (!sdp_handlers) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	endpt = ast_sip_get_pjsip_endpoint();
 	pjsip_tsx_layer_init_module(endpt);
 	pjsip_inv_usage_init(endpt, &inv_callback);
 	if (ast_sip_register_service(&session_module)) {
@@ -199,7 +285,7 @@
 
 static int unload_module(void)
 {
-	/* XXX STUB */
+	ast_sip_unregister_service(&session_module);
 	return 0;
 }
 




More information about the asterisk-commits mailing list