<p>Sungtae Kim has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18781">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_pjsip: Add pjsip option for moh allows only answered channel<br><br>This change adds an option, moh_answredonly, that when enabled will<br>process the hold request when the channel is answered.<br><br>Change-Id: I3c9b9101e4dc85338154b8004cecdd3edc227474<br>---<br>M channels/chan_pjsip.c<br>M configs/samples/pjsip.conf.sample<br>A contrib/ast-db-manage/config/versions/f407f42473e5_add_moh_answeredonly_option_to_pjsip.py<br>M include/asterisk/res_pjsip.h<br>M include/asterisk/res_pjsip_session.h<br>M res/res_pjsip/pjsip_config.xml<br>M res/res_pjsip/pjsip_configuration.c<br>M res/res_pjsip/pjsip_manager.xml<br>M res/res_pjsip_session.c<br>9 files changed, 54 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/81/18781/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c</span><br><span>index 07b9088..1afa741 100644</span><br><span>--- a/channels/chan_pjsip.c</span><br><span>+++ b/channels/chan_pjsip.c</span><br><span>@@ -1767,6 +1767,12 @@</span><br><span>               }</span><br><span>            break;</span><br><span>       case AST_CONTROL_HOLD:</span><br><span style="color: hsl(120, 100%, 40%);">+                if (channel->session->moh_answeredonly && (ast_channel_state(ast) == AST_STATE_UP)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_DEBUG, "The session '%s' is not able to oh hold with endpoint '%s'.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                 ast_sorcery_object_get_id(channel->session),</span><br><span style="color: hsl(120, 100%, 40%);">+                                       ast_sorcery_object_get_id(channel->session->endpoint));</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span>            chan_pjsip_add_hold(ast_channel_uniqueid(ast));</span><br><span>              device_buf_size = strlen(ast_channel_name(ast)) + 1;</span><br><span>                 device_buf = alloca(device_buf_size);</span><br><span>diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample</span><br><span>index 9d73843..fa77873 100644</span><br><span>--- a/configs/samples/pjsip.conf.sample</span><br><span>+++ b/configs/samples/pjsip.conf.sample</span><br><span>@@ -675,6 +675,7 @@</span><br><span> ;moh_suggest=default    ; Default Music On Hold class (default: "default")</span><br><span> ;moh_passthrough=yes    ; Pass Music On Hold through using SIP re-invites with sendonly</span><br><span>                         ; when placing on hold and sendrecv when taking off hold</span><br><span style="color: hsl(120, 100%, 40%);">+;moh_answeredonly=yes   ; Allows the only answered channel able to be music on hold.</span><br><span> ;outbound_auth= ; Authentication object used for outbound requests (default:</span><br><span>                 ; "")</span><br><span> ;outbound_proxy=        ; Proxy through which to send requests, a full SIP URI</span><br><span>diff --git a/contrib/ast-db-manage/config/versions/f407f42473e5_add_moh_answeredonly_option_to_pjsip.py b/contrib/ast-db-manage/config/versions/f407f42473e5_add_moh_answeredonly_option_to_pjsip.py</span><br><span>new file mode 100644</span><br><span>index 0000000..d67acc7</span><br><span>--- /dev/null</span><br><span>+++ b/contrib/ast-db-manage/config/versions/f407f42473e5_add_moh_answeredonly_option_to_pjsip.py</span><br><span>@@ -0,0 +1,35 @@</span><br><span style="color: hsl(120, 100%, 40%);">+"""add_moh_answeredonly_option_to_pjsip</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Revision ID: f407f42473e5</span><br><span style="color: hsl(120, 100%, 40%);">+Revises: 58e440314c2a</span><br><span style="color: hsl(120, 100%, 40%);">+Create Date: 2022-07-09 15:13:20.273405</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+"""</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# revision identifiers, used by Alembic.</span><br><span style="color: hsl(120, 100%, 40%);">+revision = 'f407f42473e5'</span><br><span style="color: hsl(120, 100%, 40%);">+down_revision = '58e440314c2a'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+from alembic import op</span><br><span style="color: hsl(120, 100%, 40%);">+import sqlalchemy as sa</span><br><span style="color: hsl(120, 100%, 40%);">+from sqlalchemy.dialects.postgresql import ENUM</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+YESNO_NAME = 'yesno_values'</span><br><span style="color: hsl(120, 100%, 40%);">+YESNO_VALUES = ['yes', 'no']</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def upgrade():</span><br><span style="color: hsl(120, 100%, 40%);">+    ############################# Enums ##############################</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    # yesno_values have already been created, so use postgres enum object</span><br><span style="color: hsl(120, 100%, 40%);">+    # type to get around "already created" issue - works okay with mysql</span><br><span style="color: hsl(120, 100%, 40%);">+    yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    op.add_column('ps_endpoints', sa.Column('moh_answeredonly', yesno_values))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def downgrade():</span><br><span style="color: hsl(120, 100%, 40%);">+    if op.get_context().bind.dialect.name == 'mssql':</span><br><span style="color: hsl(120, 100%, 40%);">+        op.drop_constraint('ck_ps_endpoints_moh_answeredonly_yesno_values','ps_endpoints')</span><br><span style="color: hsl(120, 100%, 40%);">+    with op.batch_alter_table('ps_endpoints') as batch_op:</span><br><span style="color: hsl(120, 100%, 40%);">+        batch_op.drop_column('moh_answeredonly')</span><br><span>diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h</span><br><span>index b5b5a72..06db799 100644</span><br><span>--- a/include/asterisk/res_pjsip.h</span><br><span>+++ b/include/asterisk/res_pjsip.h</span><br><span>@@ -931,6 +931,8 @@</span><br><span>  unsigned int usereqphone;</span><br><span>    /*! Whether to pass through hold and unhold using re-invites with recvonly and sendrecv */</span><br><span>   unsigned int moh_passthrough;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Allows the only answered channel able to be music on hold */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int moh_answeredonly;</span><br><span>       /*! Access control list */</span><br><span>   struct ast_acl_list *acl;</span><br><span>    /*! Restrict what IPs are allowed in the Contact header (for registration) */</span><br><span>diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h</span><br><span>index 49e6007..f6d65dd 100644</span><br><span>--- a/include/asterisk/res_pjsip_session.h</span><br><span>+++ b/include/asterisk/res_pjsip_session.h</span><br><span>@@ -229,6 +229,8 @@</span><br><span>     unsigned int ended_while_deferred:1;</span><br><span>         /*! Whether to pass through hold and unhold using re-invites with recvonly and sendrecv */</span><br><span>   unsigned int moh_passthrough:1;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! Allows the only answered channel able to be music on hold */</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int moh_answeredonly:1;</span><br><span>     /*! DTMF mode to use with this session, from endpoint but can change */</span><br><span>      enum ast_sip_dtmf_mode dtmf;</span><br><span>         /*! Initial incoming INVITE Request-URI.  NULL otherwise. */</span><br><span>diff --git a/res/res_pjsip/pjsip_config.xml b/res/res_pjsip/pjsip_config.xml</span><br><span>index e6fca2e..7003394 100644</span><br><span>--- a/res/res_pjsip/pjsip_config.xml</span><br><span>+++ b/res/res_pjsip/pjsip_config.xml</span><br><span>@@ -943,6 +943,9 @@</span><br><span>                              <configOption name="moh_passthrough" default="no"></span><br><span>                                         <synopsis>Determines whether hold and unhold will be passed through using re-INVITEs with recvonly and sendrecv to the remote side</synopsis></span><br><span>                            </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+                         <configOption name="moh_answeredonly" default="no"></span><br><span style="color: hsl(120, 100%, 40%);">+                                 <synopsis>Allows the only answered channel able to be music on hold</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                            </configOption></span><br><span>                                <configOption name="sdp_owner" default="-"></span><br><span>                                        <synopsis>String placed as the username portion of an SDP origin (o=) line.</synopsis></span><br><span>                           </configOption></span><br><span>diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c</span><br><span>index ace68d2..bbe8033 100644</span><br><span>--- a/res/res_pjsip/pjsip_configuration.c</span><br><span>+++ b/res/res_pjsip/pjsip_configuration.c</span><br><span>@@ -2123,6 +2123,7 @@</span><br><span>       ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_transfer", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowtransfer));</span><br><span>    ast_sorcery_object_field_register(sip_sorcery, "endpoint", "user_eq_phone", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, usereqphone));</span><br><span>        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "moh_passthrough", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, moh_passthrough));</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sorcery_object_field_register(sip_sorcery, "endpoint", "moh_answeredonly", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, moh_answeredonly));</span><br><span>        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_owner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpowner));</span><br><span>        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdp_session", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpsession));</span><br><span>     ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "tos_audio", "0", tos_handler, tos_audio_to_str, NULL, 0, 0);</span><br><span>diff --git a/res/res_pjsip/pjsip_manager.xml b/res/res_pjsip/pjsip_manager.xml</span><br><span>index 810a5e3..c03c25c 100644</span><br><span>--- a/res/res_pjsip/pjsip_manager.xml</span><br><span>+++ b/res/res_pjsip/pjsip_manager.xml</span><br><span>@@ -417,6 +417,9 @@</span><br><span>                                 <parameter name="MohPassthrough"></span><br><span>                                    <para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='moh_passthrough']/synopsis/node())"/></para></span><br><span>                          </parameter></span><br><span style="color: hsl(120, 100%, 40%);">+                            <parameter name="MohAnsweredOnly"></span><br><span style="color: hsl(120, 100%, 40%);">+                                    <para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='moh_answeredonly']/synopsis/node())"/></para></span><br><span style="color: hsl(120, 100%, 40%);">+                          </parameter></span><br><span>                           <parameter name="SdpOwner"></span><br><span>                                  <para><xi:include xpointer="xpointer(/docs/configInfo[@name='res_pjsip']/configFile[@name='pjsip.conf']/configObject[@name='endpoint']/configOption[@name='sdp_owner']/synopsis/node())"/></para></span><br><span>                                </parameter></span><br><span>diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c</span><br><span>index d4a857f..9051b48 100644</span><br><span>--- a/res/res_pjsip_session.c</span><br><span>+++ b/res/res_pjsip_session.c</span><br><span>@@ -3090,6 +3090,7 @@</span><br><span> </span><br><span>      session->dtmf = endpoint->dtmf;</span><br><span>        session->moh_passthrough = endpoint->moh_passthrough;</span><br><span style="color: hsl(120, 100%, 40%);">+   session->moh_answeredonly = endpoint->moh_answeredonly;</span><br><span> </span><br><span>    if (ast_sip_session_add_supplements(session)) {</span><br><span>              /* Release the ref held by session->inv_session */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18781">change 18781</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18781"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I3c9b9101e4dc85338154b8004cecdd3edc227474 </div>
<div style="display:none"> Gerrit-Change-Number: 18781 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Sungtae Kim <pchero21@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>