[asterisk-commits] mmichelson: branch mmichelson/pool_shark2 r381641 - in /team/mmichelson/pool_...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Feb 18 11:03:46 CST 2013
Author: mmichelson
Date: Mon Feb 18 11:03:41 2013
New Revision: 381641
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381641
Log:
Resolve conflict and reset automerge...again.
Modified:
team/mmichelson/pool_shark2/ (props changed)
team/mmichelson/pool_shark2/apps/app_confbridge.c
team/mmichelson/pool_shark2/channels/chan_gulp.c
team/mmichelson/pool_shark2/channels/chan_sip.c
team/mmichelson/pool_shark2/configs/res_sip.conf.sample
team/mmichelson/pool_shark2/include/asterisk/res_sip.h
team/mmichelson/pool_shark2/include/asterisk/res_sip_session.h
team/mmichelson/pool_shark2/include/asterisk/sorcery.h
team/mmichelson/pool_shark2/main/sorcery.c
team/mmichelson/pool_shark2/res/res_sip/sip_configuration.c
team/mmichelson/pool_shark2/res/res_sip_sdp_audio.c
team/mmichelson/pool_shark2/res/res_sip_session.c
team/mmichelson/pool_shark2/res/res_sorcery_config.c
team/mmichelson/pool_shark2/res/res_sorcery_memory.c
team/mmichelson/pool_shark2/tests/test_sorcery.c
Propchange: team/mmichelson/pool_shark2/
------------------------------------------------------------------------------
automerge = *
Propchange: team/mmichelson/pool_shark2/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Propchange: team/mmichelson/pool_shark2/
------------------------------------------------------------------------------
--- pool_shark2-integrated (original)
+++ pool_shark2-integrated Mon Feb 18 11:03:41 2013
@@ -1,1 +1,1 @@
-/team/group/pimp_my_sip:1-381600
+/team/group/pimp_my_sip:1-381640
Propchange: team/mmichelson/pool_shark2/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Feb 18 11:03:41 2013
@@ -1,1 +1,1 @@
-/trunk:1-381597
+/trunk:1-381630
Modified: team/mmichelson/pool_shark2/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/apps/app_confbridge.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/apps/app_confbridge.c (original)
+++ team/mmichelson/pool_shark2/apps/app_confbridge.c Mon Feb 18 11:03:41 2013
@@ -2157,10 +2157,10 @@
struct conference_bridge *bridge = NULL;
char *res = NULL;
int wordlen = strlen(word);
- struct ao2_iterator i;
-
- i = ao2_iterator_init(conference_bridges, 0);
- while ((bridge = ao2_iterator_next(&i))) {
+ struct ao2_iterator iter;
+
+ iter = ao2_iterator_init(conference_bridges, 0);
+ while ((bridge = ao2_iterator_next(&iter))) {
if (!strncasecmp(bridge->name, word, wordlen) && ++which > state) {
res = ast_strdup(bridge->name);
ao2_ref(bridge, -1);
@@ -2168,7 +2168,7 @@
}
ao2_ref(bridge, -1);
}
- ao2_iterator_destroy(&i);
+ ao2_iterator_destroy(&iter);
return res;
}
@@ -2236,10 +2236,7 @@
static char *handle_cli_confbridge_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
- struct ao2_iterator i;
- struct conference_bridge *bridge = NULL;
- struct conference_bridge tmp;
- struct conference_bridge_user *participant = NULL;
+ struct conference_bridge *bridge;
switch (cmd) {
case CLI_INIT:
@@ -2256,18 +2253,23 @@
}
if (a->argc == 2) {
+ struct ao2_iterator iter;
+
ast_cli(a->fd, "Conference Bridge Name Users Marked Locked?\n");
ast_cli(a->fd, "================================ ====== ====== ========\n");
- i = ao2_iterator_init(conference_bridges, 0);
- while ((bridge = ao2_iterator_next(&i))) {
+ iter = ao2_iterator_init(conference_bridges, 0);
+ while ((bridge = ao2_iterator_next(&iter))) {
ast_cli(a->fd, "%-32s %6i %6i %s\n", bridge->name, bridge->activeusers + bridge->waitingusers, bridge->markedusers, (bridge->locked ? "locked" : "unlocked"));
ao2_ref(bridge, -1);
}
- ao2_iterator_destroy(&i);
+ ao2_iterator_destroy(&iter);
return CLI_SUCCESS;
}
if (a->argc == 3) {
+ struct conference_bridge_user *participant;
+ struct conference_bridge tmp;
+
ast_copy_string(tmp.name, a->argv[2], sizeof(tmp.name));
bridge = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
if (!bridge) {
@@ -2657,7 +2659,7 @@
{
const char *actionid = astman_get_header(m, "ActionID");
struct conference_bridge *bridge = NULL;
- struct ao2_iterator i;
+ struct ao2_iterator iter;
char id_text[512] = "";
int totalitems = 0;
@@ -2673,8 +2675,8 @@
astman_send_listack(s, m, "Confbridge conferences will follow", "start");
/* Traverse the conference list */
- i = ao2_iterator_init(conference_bridges, 0);
- while ((bridge = ao2_iterator_next(&i))) {
+ iter = ao2_iterator_init(conference_bridges, 0);
+ while ((bridge = ao2_iterator_next(&iter))) {
totalitems++;
ao2_lock(bridge);
@@ -2695,7 +2697,7 @@
ao2_ref(bridge, -1);
}
- ao2_iterator_destroy(&i);
+ ao2_iterator_destroy(&iter);
/* Send final confirmation */
astman_append(s,
Modified: team/mmichelson/pool_shark2/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/channels/chan_gulp.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/channels/chan_gulp.c (original)
+++ team/mmichelson/pool_shark2/channels/chan_gulp.c Mon Feb 18 11:03:41 2013
@@ -108,10 +108,19 @@
.incoming_response = gulp_incoming_response,
};
-/*! \brief Function called by RTP engine to get local RTP peer */
+/*! \brief Function called by RTP engine to get local audio RTP peer */
static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
{
- return AST_RTP_GLUE_RESULT_FORBID;
+ struct ast_sip_session *session = ast_channel_tech_pvt(chan);
+
+ if (!session || !session->media[AST_SIP_MEDIA_AUDIO].rtp) {
+ return AST_RTP_GLUE_RESULT_FORBID;
+ }
+
+ ao2_ref(session->media[AST_SIP_MEDIA_AUDIO].rtp, +1);
+ *instance = session->media[AST_SIP_MEDIA_AUDIO].rtp;
+
+ return AST_RTP_GLUE_RESULT_LOCAL;
}
/*! \brief Function called by RTP engine to get peer capabilities */
@@ -157,11 +166,6 @@
ast_format_copy(ast_channel_readformat(chan), &fmt);
ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
- if (session->media.audio) {
- ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(session->media.audio, 0));
- ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(session->media.audio, 1));
- }
-
if (state == AST_STATE_RING) {
ast_channel_rings_set(chan, 1);
}
@@ -217,16 +221,16 @@
switch (ast_channel_fdno(ast)) {
case 0:
- f = ast_rtp_instance_read(session->media.audio, 0);
+ f = ast_rtp_instance_read(session->media[AST_SIP_MEDIA_AUDIO].rtp, 0);
break;
case 1:
- f = ast_rtp_instance_read(session->media.audio, 1);
+ f = ast_rtp_instance_read(session->media[AST_SIP_MEDIA_AUDIO].rtp, 1);
break;
default:
f = &ast_null_frame;
}
- if (f->frametype == AST_FRAME_VOICE) {
+ if (f && f->frametype == AST_FRAME_VOICE) {
if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
ast_format_cap_set(ast_channel_nativeformats(ast), &f->subclass.format);
@@ -257,8 +261,8 @@
ast_getformatname(ast_channel_writeformat(ast)));
return 0;
}
- if (session->media.audio) {
- res = ast_rtp_instance_write(session->media.audio, frame);
+ if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {
+ res = ast_rtp_instance_write(session->media[AST_SIP_MEDIA_AUDIO].rtp, frame);
}
break;
default:
@@ -450,7 +454,9 @@
switch (session->endpoint->dtmf) {
case AST_SIP_DTMF_RFC_4733:
- ast_rtp_instance_dtmf_begin(session->media.audio, digit);
+ if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {
+ ast_rtp_instance_dtmf_begin(session->media[AST_SIP_MEDIA_AUDIO].rtp, digit);
+ }
case AST_SIP_DTMF_NONE:
break;
case AST_SIP_DTMF_INBAND:
@@ -474,7 +480,9 @@
/* TODO: Send INFO dtmf here */
break;
case AST_SIP_DTMF_RFC_4733:
- ast_rtp_instance_dtmf_end_with_duration(session->media.audio, digit, duration);
+ if (session->media[AST_SIP_MEDIA_AUDIO].rtp) {
+ ast_rtp_instance_dtmf_end_with_duration(session->media[AST_SIP_MEDIA_AUDIO].rtp, digit, duration);
+ }
case AST_SIP_DTMF_NONE:
break;
case AST_SIP_DTMF_INBAND:
@@ -865,11 +873,9 @@
}
break;
case 183:
- ast_rtp_instance_activate(session->media.audio);
ast_queue_control(session->channel, AST_CONTROL_PROGRESS);
break;
case 200:
- ast_rtp_instance_activate(session->media.audio);
ast_queue_control(session->channel, AST_CONTROL_ANSWER);
break;
default:
Modified: team/mmichelson/pool_shark2/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/channels/chan_sip.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/channels/chan_sip.c (original)
+++ team/mmichelson/pool_shark2/channels/chan_sip.c Mon Feb 18 11:03:41 2013
@@ -14531,7 +14531,8 @@
else
ast_str_append(tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
- if (allow_notify_user_presence(p) && (data->presence_state > 0)) {
+ if (allow_notify_user_presence(p) && (data->presence_state != AST_PRESENCE_INVALID)
+ && (data->presence_state != AST_PRESENCE_NOT_SET)) {
ast_str_append(tmp, 0, "</tuple>\n");
ast_str_append(tmp, 0, "<tuple id=\"digium-presence\">\n");
ast_str_append(tmp, 0, "<status>\n");
Modified: team/mmichelson/pool_shark2/configs/res_sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/configs/res_sip.conf.sample?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/configs/res_sip.conf.sample (original)
+++ team/mmichelson/pool_shark2/configs/res_sip.conf.sample Mon Feb 18 11:03:41 2013
@@ -18,3 +18,7 @@
;timers=yes ; Enable or disable session timers support - valid options are: yes, no, required, forced
;timers_min_se=90 ; Minimum session timers expiration period, in seconds
;timers_sess_expires=1800 ; Session timers expiration period, in seconds
+;mohsuggest=example ; What musiconhold class to suggest that the peer channel use when this endpoint places them on hold
+;rtp_ipv6=yes ; Force IPv6 for RTP transport
+;rtp_symmetric=yes ; Enable symmetric RTP support
+;use_ptime=yes ; Whether to use the ptime value received from the endpoint or not
Modified: team/mmichelson/pool_shark2/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/include/asterisk/res_sip.h?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/include/asterisk/res_sip.h (original)
+++ team/mmichelson/pool_shark2/include/asterisk/res_sip.h Mon Feb 18 11:03:41 2013
@@ -213,6 +213,8 @@
AST_STRING_FIELD(context);
/*! Name of an explicit transport to use */
AST_STRING_FIELD(transport);
+ /*! Musiconhold class to suggest that the other side use when placing on hold */
+ AST_STRING_FIELD(mohsuggest);
);
/*! Identification information for this endpoint */
struct ast_party_id id;
@@ -230,12 +232,18 @@
size_t num_auths;
/*! DTMF mode to use with this endpoint */
enum ast_sip_dtmf_mode dtmf;
+ /*! Whether IPv6 RTP is enabled or not */
+ unsigned int rtp_ipv6;
+ /*! Whether symmetric RTP is enabled or not */
+ unsigned int rtp_symmetric;
+ /*! Whether to use the "ptime" attribute received from the endpoint or not */
+ unsigned int use_ptime;
/*! Enabled SIP extensions */
unsigned int extensions;
/*! Minimum session expiration period, in seconds */
- unsigned min_se;
+ unsigned int min_se;
/*! Session expiration period, in seconds */
- unsigned sess_expires;
+ unsigned int sess_expires;
/*! List of outbound registrations */
AST_LIST_HEAD_NOLOCK(, ast_sip_registration) registrations;
/*! Frequency to send OPTIONS requests to endpoint. 0 is disabled. */
Modified: team/mmichelson/pool_shark2/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/include/asterisk/res_sip_session.h?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/include/asterisk/res_sip_session.h (original)
+++ team/mmichelson/pool_shark2/include/asterisk/res_sip_session.h Mon Feb 18 11:03:41 2013
@@ -38,11 +38,25 @@
struct ast_rtp_instance;
/*!
+ * \brief Positions of various media
+ */
+enum ast_sip_session_media_position {
+ /*! \brief First is audio */
+ AST_SIP_MEDIA_AUDIO = 0,
+ /*! \brief Second is video */
+ AST_SIP_MEDIA_VIDEO,
+ /*! \brief Last is the size for media details */
+ AST_SIP_MEDIA_SIZE,
+};
+
+/*!
* \brief A structure containing SIP session media information
*/
struct ast_sip_session_media {
- /* RTP instance for audio */
- struct ast_rtp_instance *audio;
+ /*! \brief RTP instance itself */
+ struct ast_rtp_instance *rtp;
+ /*! \brief Stream is on hold */
+ unsigned int held:1;
};
/*!
@@ -66,8 +80,8 @@
AST_LIST_HEAD(, ast_sip_session_supplement) supplements;
/* Datastores added to the session by supplements to the session */
struct ao2_container *datastores;
- /* Media information */
- struct ast_sip_session_media media;
+ /* Media streams */
+ struct ast_sip_session_media media[AST_SIP_MEDIA_SIZE];
/* Serializer for tasks relating to this SIP session */
struct ast_taskprocessor *serializer;
};
@@ -158,6 +172,15 @@
* \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
* \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
*/
+ int (*negotiate_incoming_sdp_stream)(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
+ /*!
+ * \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
+ * \param session The session for which media is being added
+ * \param stream The stream on which to operate
+ * \retval 0 The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.
+ * \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
+ * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
+ */
int (*handle_incoming_sdp_stream)(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, struct pjmedia_sdp_media *stream);
/*!
* \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
@@ -168,6 +191,19 @@
* \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);
+ /*!
+ * \brief Apply a negotiated SDP media stream
+ * \param session The session for which media is being applied
+ * \param local The entire local negotiated SDP
+ * \param local_stream The local stream which to apply
+ * \param remote The entire remote negotiated SDP
+ * \param remote_stream The remote stream which to apply
+ * \retval 0 The stream was not applied by this handler. If there are other registered handlers for this stream type, they will be called.
+ * \retval <0 There was an error encountered. No further operation will take place and the current application will be abandoned.
+ * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
+ */
+ int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
+ const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
/*! Next item int he list. */
AST_LIST_ENTRY(ast_sip_session_sdp_handler) next;
};
Modified: team/mmichelson/pool_shark2/include/asterisk/sorcery.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/include/asterisk/sorcery.h?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/include/asterisk/sorcery.h (original)
+++ team/mmichelson/pool_shark2/include/asterisk/sorcery.h Mon Feb 18 11:03:41 2013
@@ -202,6 +202,9 @@
/*! \brief Callback for retrieving an object using an id */
void *(*retrieve_id)(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id);
+ /*! \brief Callback for retrieving multiple objects using a regex on their id */
+ void (*retrieve_regex)(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex);
+
/*! \brief Optional callback for retrieving an object using fields */
void *(*retrieve_fields)(const struct ast_sorcery *sorcery, void *data, const char *type, const struct ast_variable *fields);
@@ -554,6 +557,20 @@
void *ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields);
/*!
+ * \brief Retrieve multiple objects using a regular expression on their id
+ *
+ * \param sorcery Pointer to a sorcery structure
+ * \param type Type of object to retrieve
+ * \param regex Regular expression
+ *
+ * \retval non-NULL if error occurs
+ * \retval NULL success
+ *
+ * \note The provided regex is treated as extended case sensitive.
+ */
+struct ao2_container *ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex);
+
+/*!
* \brief Update an object
*
* \param sorcery Pointer to a sorcery structure
Modified: team/mmichelson/pool_shark2/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/main/sorcery.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/main/sorcery.c (original)
+++ team/mmichelson/pool_shark2/main/sorcery.c Mon Feb 18 11:03:41 2013
@@ -960,6 +960,30 @@
return object;
}
+struct ao2_container *ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
+{
+ RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
+ struct ao2_container *objects;
+ struct ao2_iterator i;
+ struct ast_sorcery_object_wizard *wizard;
+
+ if (!object_type || !(objects = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) {
+ return NULL;
+ }
+
+ i = ao2_iterator_init(object_type->wizards, 0);
+ for (; (wizard = ao2_iterator_next(&i)); ao2_ref(wizard, -1)) {
+ if (!wizard->wizard->retrieve_regex) {
+ continue;
+ }
+
+ wizard->wizard->retrieve_regex(sorcery, wizard->data, object_type->name, objects, regex);
+ }
+ ao2_iterator_destroy(&i);
+
+ return objects;
+}
+
/*! \brief Internal function which returns if the wizard has created the object */
static int sorcery_wizard_create(void *obj, void *arg, int flags)
{
Modified: team/mmichelson/pool_shark2/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/res/res_sip/sip_configuration.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/res/res_sip/sip_configuration.c (original)
+++ team/mmichelson/pool_shark2/res/res_sip/sip_configuration.c Mon Feb 18 11:03:41 2013
@@ -277,7 +277,11 @@
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_endpoint, qualify_frequency), 0, 86400);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "host", "", host_handler, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtmfmode", "rfc4733", dtmf_handler, NULL, 0, 0);
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_ipv6));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_symmetric", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_symmetric));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_ptime", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, use_ptime));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, transport));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mohsuggest", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mohsuggest));
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "100rel", "yes", prack_handler, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "timers", "yes", timers_handler, NULL, 0, 0);
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, min_se));
Modified: team/mmichelson/pool_shark2/res/res_sip_sdp_audio.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pool_shark2/res/res_sip_sdp_audio.c?view=diff&rev=381641&r1=381640&r2=381641
==============================================================================
--- team/mmichelson/pool_shark2/res/res_sip_sdp_audio.c (original)
+++ team/mmichelson/pool_shark2/res/res_sip_sdp_audio.c Mon Feb 18 11:03:41 2013
@@ -54,24 +54,35 @@
static struct ast_sched_context *sched;
/*! \brief Forward declarations for SDP handler functions */
-static int audio_handle_incoming_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, struct pjmedia_sdp_media *stream);
+static int audio_negotiate_incoming_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
static int audio_create_outgoing_sdp_stream(struct ast_sip_session *session, struct pjmedia_sdp_session *sdp);
+static int audio_apply_negotiated_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
+ const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
+
+/*! \brief Forward declaration for session supplement functions */
+static void audio_session_destroy(struct ast_sip_session *session);
/*! \brief SDP handler for 'audio' media stream */
static struct ast_sip_session_sdp_handler audio_sdp_handler = {
.id = "audio",
- .handle_incoming_sdp_stream = audio_handle_incoming_sdp_stream,
+ .negotiate_incoming_sdp_stream = audio_negotiate_incoming_sdp_stream,
.create_outgoing_sdp_stream = audio_create_outgoing_sdp_stream,
+ .apply_negotiated_sdp_stream = audio_apply_negotiated_sdp_stream,
};
+/*! \brief Session supplement for 'audio' media stream */
+static struct ast_sip_session_supplement audio_session_supplement = {
+ .session_destroy = audio_session_destroy,
+};
+
/*! \brief Internal function which creates an RTP instance */
-static int audio_create_rtp(struct ast_sip_session *session)
+static int audio_create_rtp(struct ast_sip_session *session, unsigned int ipv6)
{
pj_sockaddr addr;
char hostip[PJ_INET6_ADDRSTRLEN+2];
struct ast_sockaddr tmp;
- if (pj_gethostip(pj_AF_INET(), &addr) != PJ_SUCCESS) {
+ if (pj_gethostip(ipv6 ? pj_AF_INET6() : pj_AF_INET(), &addr) != PJ_SUCCESS) {
return -1;
}
@@ -81,137 +92,56 @@
return -1;
}
- if (!(session->media.audio = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
- return -1;
- }
-
- ast_rtp_instance_set_prop(session->media.audio, AST_RTP_PROPERTY_RTCP, 1);
-
- ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->media.audio), session->media.audio, &session->endpoint->prefs);
-
+ if (!(session->media[AST_SIP_MEDIA_AUDIO].rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
+ return -1;
+ }
+
+ ast_rtp_instance_set_prop(session->media[AST_SIP_MEDIA_AUDIO].rtp, AST_RTP_PROPERTY_RTCP, 1);
+ ast_rtp_instance_set_prop(session->media[AST_SIP_MEDIA_AUDIO].rtp, AST_RTP_PROPERTY_NAT, session->endpoint->rtp_symmetric);
+
+ ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
+ session->media[AST_SIP_MEDIA_AUDIO].rtp, &session->endpoint->prefs);
+
return 0;
}
-/*! \brief Function which handles an incoming 'audio' stream */
-static int audio_handle_incoming_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, struct pjmedia_sdp_media *stream)
-{
- int res = 1, addrs_cnt, format, othercapability = 0;
+/*! \brief Function which negotiates an incoming 'audio' stream */
+static int audio_negotiate_incoming_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
+{
char host[NI_MAXHOST];
- struct ast_sockaddr *addrs;
- struct ast_rtp_codecs codecs;
- const pjmedia_sdp_attr *attr;
- struct ast_format_cap *cap, *jointcap = NULL, *peercap = NULL;
-// struct ast_format fmt;
-
- /* If the stream has been rejected stop media if active */
- if (!stream->desc.port) {
- if (session->media.audio) {
- ast_rtp_instance_stop(session->media.audio);
- }
-
- return 1;
- }
-
- /* Create an RTP instance if need be */
- if (!session->media.audio && audio_create_rtp(session)) {
- return -1;
- }
-
- if (!stream->conn) {
- snprintf(host, sizeof(host), "%.*s", (int) pj_strlen(&sdp->conn->addr), pj_strbuf(&sdp->conn->addr));
- } else {
- snprintf(host, sizeof(host), "%.*s", (int) pj_strlen(&stream->conn->addr), pj_strbuf(&stream->conn->addr));
- }
+ RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
+
+ /* If no audio formats have been configured reject this stream */
+ if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_AUDIO)) {
+ return 0;
+ }
+
+ ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
/* Ensure that the address provided is valid */
- if ((addrs_cnt = ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC)) <= 0) {
- ast_log(LOG_ERROR, "Failed to resolve %s\n", host);
- /* The provided host was actually invalid so we kill the session as it would just end up being broken */
- if (session->channel) {
- ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- }
- return -1;
- }
-
- /* To properly apply formats to the channel we need to keep track of capabilities */
- if (!(cap = ast_format_cap_alloc_nolock()) ||
- !(peercap = ast_format_cap_alloc_nolock())) {
- ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n");
- res = -1;
- goto cleanup;
- }
-
- /* Apply connection information to the RTP instance */
- ast_sockaddr_set_port(addrs, stream->desc.port);
- ast_rtp_instance_set_remote_address(session->media.audio, addrs);
- ast_free(addrs);
-
- ast_rtp_codecs_payloads_initialize(&codecs);
-
- /* Iterate through provided formats */
- for (format = 0; format < stream->desc.fmt_count; format++) {
- /* The payload is kept as a string for things like t38 but for audio it is always numerical */
- ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, pj_strtoul(&stream->desc.fmt[format]));
-
- /* Look for the optional rtpmap attribute */
- if ((attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[format]))) {
- pjmedia_sdp_rtpmap *rtpmap;
-
- /* Interpret the attribute as an rtpmap */
- if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
- char name[32];
-
- snprintf(name, sizeof(name), "%.*s", (int) pj_strlen(&rtpmap->enc_name), pj_strbuf(&rtpmap->enc_name));
- ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&stream->desc.fmt[format]),
- "audio", name, 0, rtpmap->clock_rate);
- }
- }
- }
-
- ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
-
- /* Using the configured codecs and the codecs in this SDP we determine the joint formats for *audio only* */
- ast_format_cap_copy(cap, session->endpoint->codecs);
- ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_VIDEO);
-
- if (!(jointcap = ast_format_cap_joint(cap, peercap))) {
- char usbuf[64];
- char thembuf[64];
- if (session->channel) {
- ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- }
- ast_getformatname_multiple(usbuf, sizeof(usbuf), cap);
- ast_getformatname_multiple(thembuf, sizeof(thembuf), peercap);
- ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
- res = -1;
- goto cleanup;
- }
-
- ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session->media.audio), session->media.audio);
-
- /* Now that we have joint formats for audio remove the existing ones from the channel and add the new ones */
-// ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel));
-// ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
-// ast_format_cap_append(cap, jointcap);
-
- /* Apply the new formats to the channel, potentially changing read/write formats while doing so */
-// ast_format_cap_copy(ast_channel_nativeformats(session->channel), cap);
-// ast_codec_choose(&session->endpoint->prefs, cap, 1, &fmt);
-// ast_set_read_format(session->channel, &fmt);
-// ast_set_write_format(session->channel, &fmt);
-
-cleanup:
- ast_format_cap_destroy(peercap);
- ast_format_cap_destroy(jointcap);
- ast_format_cap_destroy(cap);
- ast_rtp_codecs_payloads_destroy(&codecs);
-
- return res;
+ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
+ /* The provided host was actually invalid so we error out this negotiation */
+ return -1;
+ }
+
+ /* Using the connection information create an appropriate RTP instance */
+ if (!session->media[AST_SIP_MEDIA_AUDIO].rtp && audio_create_rtp(session, ast_sockaddr_is_ipv6(addrs))) {
+ return -1;
+ }
+
+ /* pjmedia takes care of the formats and such */
+ return 1;
}
/*! \brief Function which creates an outgoing 'audio' stream */
static int audio_create_outgoing_sdp_stream(struct ast_sip_session *session, struct pjmedia_sdp_session *sdp)
{
+ static const pj_str_t STR_AUDIO = { "audio", 5};
+ static const pj_str_t STR_IN = { "IN", 2 };
+ static const pj_str_t STR_IP4 = { "IP4", 3};
+ static const pj_str_t STR_IP6 = { "IP6", 3};
+ static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
+ static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
pj_pool_t *pool = session->inv_session->pool_active;
pjmedia_sdp_media *media;
struct ast_sockaddr addr;
@@ -223,7 +153,7 @@
if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_AUDIO)) {
/* If no audio formats are configured don't add a stream */
return 0;
- } else if (!session->media.audio && audio_create_rtp(session)) {
+ } else if (!session->media[AST_SIP_MEDIA_AUDIO].rtp && audio_create_rtp(session, session->endpoint->rtp_ipv6)) {
return -1;
}
@@ -233,13 +163,13 @@
}
/* TODO: This should eventually support SRTP */
- pj_strdup2(pool, &media->desc.media, "audio");
- pj_strdup2(pool, &media->desc.transport, "RTP/AVP");
+ media->desc.media = STR_AUDIO;
+ media->desc.transport = STR_RTP_AVP;
/* Add connection level details */
- ast_rtp_instance_get_local_address(session->media.audio, &addr);
- pj_strdup2(pool, &media->conn->net_type, "IN");
- pj_strdup2(pool, &media->conn->addr_type, (ast_sockaddr_is_ipv6(&addr) && !ast_sockaddr_is_ipv4_mapped(&addr)) ? "IP6" : "IP4");
+ ast_rtp_instance_get_local_address(session->media[AST_SIP_MEDIA_AUDIO].rtp, &addr);
+ media->conn->net_type = STR_IN;
+ media->conn->addr_type = (ast_sockaddr_is_ipv6(&addr) && !ast_sockaddr_is_ipv4_mapped(&addr)) ? STR_IP6 : STR_IP4;
pj_strdup2(pool, &media->conn->addr, ast_sockaddr_stringify_addr_remote(&addr));
media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
media->desc.port_count = 1;
@@ -249,13 +179,14 @@
struct ast_format format;
int rtp_code;
pjmedia_sdp_rtpmap rtpmap;
- struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session->media.audio)->pref;
+ struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp)->pref;
if (!ast_codec_pref_index(&session->endpoint->prefs, index, &format)) {
break;
} else if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) {
continue;
- } else if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session->media.audio), 1, &format, 0)) == -1) {
+ } else if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
+ 1, &format, 0)) == -1) {
return -1;
}
@@ -282,7 +213,8 @@
int rtp_code;
pjmedia_sdp_rtpmap rtpmap;
- if (!(noncodec & index) || (rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session->media.audio), 0, NULL, index)) == -1) {
+ if (!(noncodec & index) || (rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
+ 0, NULL, index)) == -1) {
continue;
}
@@ -310,10 +242,167 @@
media->attr[media->attr_count++] = attr;
}
+ /* Add the sendrecv attribute - we purposely don't keep track because pjmedia-sdp will automatically change our offer for us */
+ attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
+ attr->name = STR_SENDRECV;
+ media->attr[media->attr_count++] = attr;
+
/* Add the media stream to the SDP */
sdp->media[sdp->media_count++] = media;
return 1;
+}
+
+/*! \brief Function which applies a negotiated SDP stream */
+static int audio_apply_negotiated_sdp_stream(struct ast_sip_session *session, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
+ const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
+{
+ int format, othercapability = 0;
+ char host[NI_MAXHOST];
+ RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
+ struct ast_rtp_codecs codecs;
+ const pjmedia_sdp_attr *attr;
+ RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy);
+ RAII_VAR(struct ast_format_cap *, jointcap, NULL, ast_format_cap_destroy);
+ RAII_VAR(struct ast_format_cap *, peercap, NULL, ast_format_cap_destroy);
+ struct ast_format fmt;
+
+ /* Create an RTP instance if need be */
+ if (!session->media[AST_SIP_MEDIA_AUDIO].rtp && audio_create_rtp(session, session->endpoint->rtp_ipv6)) {
+ return -1;
+ }
+
+ ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host));
+
+ /* Ensure that the address provided is valid */
+ if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) {
+ /* The provided host was actually invalid so we error out this negotiation */
+ return -1;
+ }
+
+ /* To properly apply formats to the channel we need to keep track of capabilities */
+ if (!(cap = ast_format_cap_alloc_nolock()) ||
+ !(peercap = ast_format_cap_alloc_nolock())) {
+ ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n");
+ return -1;
+ }
+
+ /* Apply connection information to the RTP instance */
+ ast_sockaddr_set_port(addrs, remote_stream->desc.port);
+ ast_rtp_instance_set_remote_address(session->media[AST_SIP_MEDIA_AUDIO].rtp, addrs);
+
+ ast_rtp_codecs_payloads_initialize(&codecs);
+
+ /* Iterate through provided formats */
+ for (format = 0; format < local_stream->desc.fmt_count; format++) {
+ /* The payload is kept as a string for things like t38 but for audio it is always numerical */
+ ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]));
+
+ /* Look for the optional rtpmap attribute */
+ if ((attr = pjmedia_sdp_media_find_attr2(local_stream, "rtpmap", &local_stream->desc.fmt[format]))) {
+ pjmedia_sdp_rtpmap *rtpmap;
+
+ /* Interpret the attribute as an rtpmap */
+ if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
+ char name[32];
+
+ ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
+ ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]),
+ "audio", name, 0, rtpmap->clock_rate);
+ }
+ }
+ }
+
+ ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
+
+ /* Apply packetization if available and configured to do so */
+ if (session->endpoint->use_ptime && (attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) {
+ pj_str_t value = attr->value;
+ unsigned long framing = pj_strtoul(pj_strltrim(&value));
+ int codec;
+ struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp)->pref;
+
+ for (codec = 0; codec < AST_RTP_MAX_PT; codec++) {
+ struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(
+ session->media[AST_SIP_MEDIA_AUDIO].rtp), codec);
+
+ if (!format.asterisk_format) {
+ continue;
+ }
+
+ ast_codec_pref_setsize(pref, &format.format, framing);
+ }
+
+ ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
+ session->media[AST_SIP_MEDIA_AUDIO].rtp, pref);
+ }
+
+ /* Using the configured codecs and the codecs in this SDP we determine the joint formats for *audio only* */
+ ast_format_cap_copy(cap, session->endpoint->codecs);
+ ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_VIDEO);
+
+ if (!(jointcap = ast_format_cap_joint(cap, peercap))) {
+ char usbuf[64], thembuf[64];
+
+ ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+ ast_getformatname_multiple(usbuf, sizeof(usbuf), cap);
+ ast_getformatname_multiple(thembuf, sizeof(thembuf), peercap);
+ ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
+
+ ast_rtp_codecs_payloads_destroy(&codecs);
+ return -1;
+ }
+
+ ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session->media[AST_SIP_MEDIA_AUDIO].rtp),
+ session->media[AST_SIP_MEDIA_AUDIO].rtp);
+
+ /* Now that we have joint formats for audio remove the existing ones from the channel and add the new ones */
+ ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel));
+ ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
+ ast_format_cap_append(cap, jointcap);
+
+ /* Apply the new formats to the channel, potentially changing read/write formats while doing so */
+ ast_format_cap_copy(ast_channel_nativeformats(session->channel), cap);
+ ast_codec_choose(&session->endpoint->prefs, cap, 1, &fmt);
+ ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
+ ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
+ ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
+ ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+
+ ast_channel_set_fd(session->channel, 0, ast_rtp_instance_fd(session->media[AST_SIP_MEDIA_AUDIO].rtp, 0));
+ ast_channel_set_fd(session->channel, 1, ast_rtp_instance_fd(session->media[AST_SIP_MEDIA_AUDIO].rtp, 1));
+
+ if (session->media[AST_SIP_MEDIA_AUDIO].held && (!ast_sockaddr_isnull(addrs) ||
[... 538 lines stripped ...]
More information about the asterisk-commits
mailing list