summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-11-03 14:45:01 +0000
committerJoshua Colp <jcolp@digium.com>2014-11-03 14:45:01 +0000
commitac091d41844a9a4a0f7d539164bcd154351b6da7 (patch)
tree84ec4d1350b4e6d1d1498c4ceabd2b5484f3947d /res
parent285be15aaf0469055d3392ecd73eb24395e49059 (diff)
chan_pjsip: Add support for passing hold and unhold requests through.
This change adds an option, moh_passthrough, that when enabled will pass hold and unhold requests through using a SIP re-invite. When placing on hold a re-invite with sendonly will be sent and when taking off hold a re-invite with sendrecv will be sent. This allows remote servers to handle the musiconhold instead of the local Asterisk instance being responsible. Review: https://reviewboard.asterisk.org/r/4103/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@427112 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip.c6
-rw-r--r--res/res_pjsip/pjsip_configuration.c1
-rw-r--r--res/res_pjsip_sdp_rtp.c11
3 files changed, 13 insertions, 5 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index b350b7b77..dcf771bb3 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -576,6 +576,9 @@
<configOption name="user_eq_phone" default="no">
<synopsis>Determines whether a user=phone parameter is placed into the request URI if the user is determined to be a phone number</synopsis>
</configOption>
+ <configOption name="moh_passthrough" default="no">
+ <synopsis>Determines whether hold and unhold will be passed through using re-INVITEs with recvonly and sendrecv to the remote side</synopsis>
+ </configOption>
<configOption name="sdp_owner" default="-">
<synopsis>String placed as the username portion of an SDP origin (o=) line.</synopsis>
</configOption>
@@ -1560,6 +1563,9 @@
<parameter name="UserEqPhone">
<para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='user_eq_phone']/synopsis/node())"/></para>
</parameter>
+ <parameter name="MohPassthrough">
+ <para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='moh_passthrough']/synopsis/node())"/></para>
+ </parameter>
<parameter name="SdpOwner">
<para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='sdp_owner']/synopsis/node())"/></para>
</parameter>
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index dabbfaed8..798066777 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1733,6 +1733,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "record_off_feature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, info.recording.offfeature));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_transfer", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowtransfer));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "user_eq_phone", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, usereqphone));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "moh_passthrough", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, moh_passthrough));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_owner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpowner));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_session", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpsession));
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "tos_audio", "0", tos_handler, tos_audio_to_str, NULL, 0, 0);
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 1f863008f..74c980d39 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -887,6 +887,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
static const pj_str_t STR_IP4 = { "IP4", 3};
static const pj_str_t STR_IP6 = { "IP6", 3};
static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
+ static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
pjmedia_sdp_media *media;
char hostip[PJ_INET6_ADDRSTRLEN+2];
struct ast_sockaddr addr;
@@ -1046,7 +1047,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
/* 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;
+ attr->name = !session_media->locally_held ? STR_SENDRECV : STR_SENDONLY;
media->attr[media->attr_count++] = attr;
/* Add the media stream to the SDP */
@@ -1122,18 +1123,18 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
if (ast_sockaddr_isnull(addrs) ||
ast_sockaddr_is_any(addrs) ||
pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
- if (!session_media->held) {
+ if (!session_media->remotely_held) {
/* The remote side has put us on hold */
ast_queue_hold(session->channel, session->endpoint->mohsuggest);
ast_rtp_instance_stop(session_media->rtp);
ast_queue_frame(session->channel, &ast_null_frame);
- session_media->held = 1;
+ session_media->remotely_held = 1;
}
- } else if (session_media->held) {
+ } else if (session_media->remotely_held) {
/* The remote side has taken us off hold */
ast_queue_unhold(session->channel);
ast_queue_frame(session->channel, &ast_null_frame);
- session_media->held = 0;
+ session_media->remotely_held = 0;
}
return 1;