[Asterisk-code-review] channel/chan_pjsip: add dialplan function for music on hold (...asterisk[16])
Friendly Automation
asteriskteam at digium.com
Mon Oct 7 07:55:35 CDT 2019
Friendly Automation has submitted this change and it was merged. ( https://gerrit.asterisk.org/c/asterisk/+/12929 )
Change subject: channel/chan_pjsip: add dialplan function for music on hold
......................................................................
channel/chan_pjsip: add dialplan function for music on hold
Add a new dialplan function PJSIP_MOH_PASSTHROUGH that allows
the on-hold behavior to be controlled on a per-call basis
ASTERISK-28542 #close
Change-Id: Iebe905b2ad6dbaa87ab330267147180b05a3c3a8
---
M channels/chan_pjsip.c
M channels/pjsip/dialplan_functions.c
M channels/pjsip/include/dialplan_functions.h
A doc/CHANGES-staging/chan_pjsip_moh_passthrough.txt
M include/asterisk/res_pjsip_session.h
M res/res_pjsip_session.c
6 files changed, 113 insertions(+), 2 deletions(-)
Approvals:
Joshua Colp: Looks good to me, but someone else must approve
Benjamin Keith Ford: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 5b91dfd..c091082 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -1744,7 +1744,7 @@
device_buf = alloca(device_buf_size);
ast_channel_get_device_name(ast, device_buf, device_buf_size);
ast_devstate_changed_literal(AST_DEVICE_ONHOLD, 1, device_buf);
- if (!channel->session->endpoint->moh_passthrough) {
+ if (!channel->session->moh_passthrough) {
ast_moh_start(ast, data, NULL);
} else {
if (ast_sip_push_task(channel->session->serializer, remote_send_hold, ao2_bump(channel->session))) {
@@ -1760,7 +1760,7 @@
device_buf = alloca(device_buf_size);
ast_channel_get_device_name(ast, device_buf, device_buf_size);
ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, 1, device_buf);
- if (!channel->session->endpoint->moh_passthrough) {
+ if (!channel->session->moh_passthrough) {
ast_moh_stop(ast);
} else {
if (ast_sip_push_task(channel->session->serializer, remote_send_unhold, ao2_bump(channel->session))) {
@@ -3228,6 +3228,12 @@
.write = pjsip_acf_dtmf_mode_write
};
+static struct ast_custom_function moh_passthrough_function = {
+ .name = "PJSIP_MOH_PASSTHROUGH",
+ .read = pjsip_acf_moh_passthrough_read,
+ .write = pjsip_acf_moh_passthrough_write
+};
+
static struct ast_custom_function session_refresh_function = {
.name = "PJSIP_SEND_SESSION_REFRESH",
.write = pjsip_acf_session_refresh_write,
@@ -3280,6 +3286,11 @@
goto end;
}
+ if (ast_custom_function_register(&moh_passthrough_function)) {
+ ast_log(LOG_WARNING, "Unable to register PJSIP_MOH_PASSTHROUGH dialplan function\n");
+ goto end;
+ }
+
if (ast_custom_function_register(&session_refresh_function)) {
ast_log(LOG_WARNING, "Unable to register PJSIP_SEND_SESSION_REFRESH dialplan function\n");
goto end;
@@ -3325,6 +3336,7 @@
ast_sip_session_unregister_supplement(&call_pickup_supplement);
ast_sip_unregister_service(&refer_callback_module);
ast_custom_function_unregister(&dtmf_mode_function);
+ ast_custom_function_unregister(&moh_passthrough_function);
ast_custom_function_unregister(&media_offer_function);
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
@@ -3352,6 +3364,7 @@
ast_sip_unregister_service(&refer_callback_module);
ast_custom_function_unregister(&dtmf_mode_function);
+ ast_custom_function_unregister(&moh_passthrough_function);
ast_custom_function_unregister(&media_offer_function);
ast_custom_function_unregister(&chan_pjsip_dial_contacts_function);
ast_custom_function_unregister(&chan_pjsip_parse_uri_function);
diff --git a/channels/pjsip/dialplan_functions.c b/channels/pjsip/dialplan_functions.c
index 2081bad..7cc4506 100644
--- a/channels/pjsip/dialplan_functions.c
+++ b/channels/pjsip/dialplan_functions.c
@@ -80,6 +80,19 @@
<para>This function uses the same DTMF mode naming as the dtmf_mode configuration option</para>
</description>
</function>
+<function name="PJSIP_MOH_PASSTHROUGH" language="en_US">
+ <synopsis>
+ Get or change the on-hold behavior for a SIP call.
+ </synopsis>
+ <syntax>
+ </syntax>
+ <description>
+ <para>When read, returns the current moh passthrough mode</para>
+ <para>When written, sets the current moh passthrough mode</para>
+ <para>If <replaceable>yes</replaceable>, on-hold re-INVITEs are sent. If <replaceable>no</replaceable>, music on hold is generated.</para>
+ <para>This function can be used to override the moh_passthrough configuration option</para>
+ </description>
+</function>
<function name="PJSIP_SEND_SESSION_REFRESH" language="en_US">
<synopsis>
W/O: Initiate a session refresh via an UPDATE or re-INVITE on an established media session
@@ -1431,6 +1444,34 @@
return 0;
}
+int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+ struct ast_sip_channel_pvt *channel;
+
+ if (!chan) {
+ ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
+ return -1;
+ }
+
+ if (len < 3) {
+ ast_log(LOG_WARNING, "%s: buffer too small\n", cmd);
+ return -1;
+ }
+
+ ast_channel_lock(chan);
+ if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
+ ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
+ ast_channel_unlock(chan);
+ return -1;
+ }
+
+ channel = ast_channel_tech_pvt(chan);
+ strncpy(buf, AST_YESNO(channel->session->moh_passthrough), len);
+
+ ast_channel_unlock(chan);
+ return 0;
+}
+
struct refresh_data {
struct ast_sip_session *session;
enum ast_sip_session_refresh_method method;
@@ -1574,6 +1615,30 @@
return ast_sip_push_task_wait_serializer(channel->session->serializer, dtmf_mode_refresh_cb, &rdata);
}
+int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+ struct ast_sip_channel_pvt *channel;
+
+ if (!chan) {
+ ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
+ return -1;
+ }
+
+ ast_channel_lock(chan);
+ if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
+ ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
+ ast_channel_unlock(chan);
+ return -1;
+ }
+
+ channel = ast_channel_tech_pvt(chan);
+ channel->session->moh_passthrough = ast_true(value);
+
+ ast_channel_unlock(chan);
+
+ return 0;
+}
+
static int refresh_write_cb(void *obj)
{
struct refresh_data *data = obj;
diff --git a/channels/pjsip/include/dialplan_functions.h b/channels/pjsip/include/dialplan_functions.h
index a9332a2..d0bf130 100644
--- a/channels/pjsip/include/dialplan_functions.h
+++ b/channels/pjsip/include/dialplan_functions.h
@@ -73,6 +73,31 @@
int pjsip_acf_dtmf_mode_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
/*!
+ * \brief PJSIP_MOH_PASSTHROUGH function read callback
+ * \param chan The channel the function is called on
+ * \param cmd The name of the function
+ * \param data Arguments passed to the function
+ * \param buf Out buffer that should be populated with the data
+ * \param len Size of the buffer
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int pjsip_acf_moh_passthrough_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len);
+
+/*!
+ * \brief PJSIP_MOH_PASSTHROUGH function write callback
+ * \param chan The channel the function is called on
+ * \param cmd The name of the function
+ * \param data Arguments passed to the function
+ * \param value Value to be set by the function
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int pjsip_acf_moh_passthrough_write(struct ast_channel *chan, const char *cmd, char *data, const char *value);
+
+/*!
* \brief PJSIP_MEDIA_OFFER function read callback
* \param chan The channel the function is called on
* \param cmd The name of the function
diff --git a/doc/CHANGES-staging/chan_pjsip_moh_passthrough.txt b/doc/CHANGES-staging/chan_pjsip_moh_passthrough.txt
new file mode 100644
index 0000000..cb874a5
--- /dev/null
+++ b/doc/CHANGES-staging/chan_pjsip_moh_passthrough.txt
@@ -0,0 +1,5 @@
+Subject: chan_pjsip
+
+A new dialplan function, PJSIP_MOH_PASSTRHOUGH, has been added to chan_pjsip. This
+allows the behaviour of the moh_passthrough endpoint option to be read or changed
+in the dialplan. This allows control on a per-call basis.
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index a6f8bde..43ac9c0 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -211,6 +211,8 @@
unsigned int defer_end:1;
/*! Session end (remote hangup) requested while termination deferred */
unsigned int ended_while_deferred:1;
+ /*! Whether to pass through hold and unhold using re-invites with recvonly and sendrecv */
+ unsigned int moh_passthrough:1;
/*! DTMF mode to use with this session, from endpoint but can change */
enum ast_sip_dtmf_mode dtmf;
/*! Initial incoming INVITE Request-URI. NULL otherwise. */
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 5fe8836..dc476ff 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -2306,6 +2306,7 @@
session->inv_session = inv_session;
session->dtmf = endpoint->dtmf;
+ session->moh_passthrough = endpoint->moh_passthrough;
if (ast_sip_session_add_supplements(session)) {
/* Release the ref held by session->inv_session */
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/12929
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-Change-Id: Iebe905b2ad6dbaa87ab330267147180b05a3c3a8
Gerrit-Change-Number: 12929
Gerrit-PatchSet: 5
Gerrit-Owner: Torrey Searle <tsearle at gmail.com>
Gerrit-Reviewer: Benjamin Keith Ford <bford at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Sean Bright <sean.bright at gmail.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20191007/5dc58fdd/attachment-0001.html>
More information about the asterisk-code-review
mailing list