<p>Christian Savinovich has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11627">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">mwi_subscribe_replaces_unsolicited:<br><br>Fixes an bug whereby multiple NOTIFYs were replied back to endpoint when a<br>REGISTER was received.  This occurred when parameter<br>mwi_subscribe_replaces_unsolicited is set to yes in pjsip.conf.<br>The underlying problem here is that the<br>endpoint_receives_unsolicited_mwi_for_mailbox() function in res/res_pjsip_mwi.c<br>is sort of an overloaded function. When invoked from mwi_validate_for_aor() you<br>DO want to have the subscribe_replaces_unsolicited() logic occur whereby it<br>unsubscribes from stasis. When invoked from<br>create_mwi_subscriptions_for_endpoint you DO NOT want to have the<br>subscribe_replaces_unsolicited logic occur.The function should have a parameter<br>added to it which determines whether the logic is invoked or not.<br>The bug itself occurs because there are multiple mwi_subscription structures<br>for the mailbox, the logic which sends the NOTIFY when a REGISTER occurs goes<br>through all looking for mwi_subscription structures with the AOR. It finds<br>these multiple structures, calculates message count on them (despite having<br>no stasis subscriptions), and sends a NOTIFY.<br>Note: This fix does not restore back unsolicted NOTIFYs in the event<br>all subscriptions on a given AOR go away.  It was decided to create<br>a new issue for that.<br><br>Change-Id: I8f77c33b9b4d374d510aa5ecd4f700a77107d8d4<br>---<br>M res/res_pjsip_mwi.c<br>1 file changed, 31 insertions(+), 12 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/27/11627/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c</span><br><span>index abd7ac0..c5e7963 100644</span><br><span>--- a/res/res_pjsip_mwi.c</span><br><span>+++ b/res/res_pjsip_mwi.c</span><br><span>@@ -119,6 +119,10 @@</span><br><span>         char *aors;</span><br><span>  /*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */</span><br><span>    unsigned int is_solicited;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! identifies if user wants to mute unsolicited NOTIFYs if subscription</span><br><span style="color: hsl(120, 100%, 40%);">+      *  exists.</span><br><span style="color: hsl(120, 100%, 40%);">+    */</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned int is_subscribe_replaces_unsolicited;</span><br><span>      /*! Identifier for the subscription.</span><br><span>          * The identifier is the same as the corresponding endpoint's stasis ID.</span><br><span>          * Used as a hash key</span><br><span>@@ -498,7 +502,6 @@</span><br><span>          .body_type = AST_SIP_MESSAGE_ACCUMULATOR,</span><br><span>            .body_data = mwi_data->counter,</span><br><span>   };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   if (ast_sip_create_request("NOTIFY", NULL, endpoint, NULL, contact, &tdata)) {</span><br><span>                 ast_log(LOG_WARNING, "Unable to create unsolicited NOTIFY request to endpoint %s URI %s\n", sub->id, contact->uri);</span><br><span>          return 0;</span><br><span>@@ -677,7 +680,15 @@</span><br><span>             return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (sub->is_subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct ast_sip_endpoint *endpoint = ast_sip_subscription_get_endpoint(sub->sip_sub);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   return;</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>  send_unsolicited_mwi_notify(sub, &counter);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static int unsubscribe_stasis(void *obj, void *arg, int flags)</span><br><span>@@ -710,7 +721,6 @@</span><br><span> static void mwi_ds_destroy(void *data)</span><br><span> {</span><br><span>    struct mwi_subscription *sub = data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>         ao2_ref(sub, -1);</span><br><span> }</span><br><span> </span><br><span>@@ -744,11 +754,12 @@</span><br><span>  *</span><br><span>  * \param endpoint The endpoint to check</span><br><span>  * \param mailbox The candidate mailbox</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param invokedByValidate 1 or 0 if called from mwi_validate_for_aor</span><br><span>  * \retval 0 The endpoint does not receive unsolicited MWI for this mailbox</span><br><span>  * \retval 1 The endpoint receives unsolicited MWI for this mailbox</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint *endpoint,</span><br><span style="color: hsl(0, 100%, 40%);">-         const char *mailbox)</span><br><span style="color: hsl(120, 100%, 40%);">+static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint *endpoint, </span><br><span style="color: hsl(120, 100%, 40%);">+            const char *mailbox, int invokedByValidate)</span><br><span> {</span><br><span>     struct ao2_iterator *mwi_subs;</span><br><span>       struct mwi_subscription *mwi_sub;</span><br><span>@@ -765,13 +776,19 @@</span><br><span> </span><br><span>                mwi_stasis = ao2_find(mwi_sub->stasis_subs, mailbox, OBJ_SEARCH_KEY);</span><br><span>             if (mwi_stasis) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             unsubscribe_stasis(mwi_stasis, NULL, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                                ao2_unlink(mwi_sub->stasis_subs, mwi_stasis);</span><br><span style="color: hsl(0, 100%, 40%);">-                        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (invokedByValidate) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              if (endpoint->subscription.mwi.subscribe_replaces_unsolicited) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                   mwi_sub->is_subscribe_replaces_unsolicited = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                                    unsubscribe_stasis(mwi_stasis, NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ao2_unlink(mwi_sub->stasis_subs, mwi_stasis);</span><br><span style="color: hsl(120, 100%, 40%);">+                              } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ret = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                              }</span><br><span style="color: hsl(120, 100%, 40%);">+                             ao2_cleanup(mwi_stasis);</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span style="color: hsl(120, 100%, 40%);">+                     else {</span><br><span>                               ret = 1;</span><br><span>                     }</span><br><span style="color: hsl(0, 100%, 40%);">-                       ao2_cleanup(mwi_stasis);</span><br><span>             }</span><br><span>    }</span><br><span> </span><br><span>@@ -808,7 +825,8 @@</span><br><span>                  continue;</span><br><span>            }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* parameter 3 = 1 means "invoked-from-function-mwi-validate-for-aor" */</span><br><span style="color: hsl(120, 100%, 40%);">+            if (endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox, 1)) {</span><br><span>                   ast_debug(1, "Endpoint '%s' already configured for unsolicited MWI for mailbox '%s'. "</span><br><span>                                     "Denying MWI subscription to %s\n", ast_sorcery_object_get_id(endpoint), mailbox,</span><br><span>                                  ast_sorcery_object_get_id(aor));</span><br><span>@@ -1021,7 +1039,7 @@</span><br><span> }</span><br><span> </span><br><span> static void mwi_to_ami(struct ast_sip_subscription *sub,</span><br><span style="color: hsl(0, 100%, 40%);">-                  struct ast_str **buf)</span><br><span style="color: hsl(120, 100%, 40%);">+          struct ast_str **buf)</span><br><span> {</span><br><span>   struct mwi_subscription *mwi_sub;</span><br><span>    struct ast_datastore *mwi_datastore;</span><br><span>@@ -1127,8 +1145,9 @@</span><br><span>                 struct mwi_stasis_subscription *mwi_stasis_sub;</span><br><span> </span><br><span>          /* check if subscription exists */</span><br><span style="color: hsl(120, 100%, 40%);">+            /* parameter 3 = 0 means "not-invoked-from-function-mwi-validate-for-aor" */</span><br><span>               if (ast_strlen_zero(mailbox) ||</span><br><span style="color: hsl(0, 100%, 40%);">-                 (!aggregate_sub && endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       (!aggregate_sub && endpoint_receives_unsolicited_mwi_for_mailbox(endpoint, mailbox, 0))) {</span><br><span>                   continue;</span><br><span>            }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11627">change 11627</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/+/11627"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I8f77c33b9b4d374d510aa5ecd4f700a77107d8d4 </div>
<div style="display:none"> Gerrit-Change-Number: 11627 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Christian Savinovich <csavinovich@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>