[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