<p>Igor Goncharovsky has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7880">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_unistim: Fix hold function ability to lock/crash asterisk<br><br>This patch fix chan_unistim hold functions to correctly support<br>hold function in different states possible in case of multiple lines<br>established on the phone<br><br>ASTERISK-26596 #close<br><br>Change-Id: Ib1e04e482e7c8939607a42d7fddacc07e26e14d4<br>---<br>M channels/chan_unistim.c<br>1 file changed, 45 insertions(+), 18 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/80/7880/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c<br>index b82b140..20c3611 100644<br>--- a/channels/chan_unistim.c<br>+++ b/channels/chan_unistim.c<br>@@ -360,6 +360,7 @@<br>  int softkey;                    /*! Softkey assigned */<br>       pthread_t ss_thread;            /*! unistim_ss thread handle */<br>       int alreadygone;<br>+     int holding;                    /*! this subchannel holds someone */<br>  signed char ringvolume;<br>       signed char ringstyle;<br>        int moh;                                        /*!< Music on hold in progress */<br>@@ -2498,6 +2499,24 @@<br>  return sub;<br> }<br> <br>+static struct unistim_subchannel* get_sub_holding(struct unistim_device *device, int type, int holding)<br>+{<br>+     struct unistim_subchannel *sub = NULL;<br>+<br>+    AST_LIST_LOCK(&device->subs);<br>+ AST_LIST_TRAVERSE(&device->subs, sub, list) {<br>+         if (!sub) {<br>+                  continue;<br>+            }<br>+            if (sub->subtype == type && sub->holding == holding) {<br>+                 break;<br>+               }<br>+    }<br>+    AST_LIST_UNLOCK(&device->subs);<br>+<br>+    return sub;<br>+}<br>+<br> static void sub_start_silence(struct unistimsession *pte, struct unistim_subchannel *sub)<br> {<br>    /* Silence our channel */<br>@@ -2535,13 +2554,12 @@<br>            return;<br>       }<br>     sub->moh = 1;<br>-     sub->subtype = SUB_ONHOLD;<br>+        sub->holding = 1;<br>  send_favorite_short(sub->softkey, FAV_ICON_ONHOLD_BLACK + FAV_BLINK_SLOW, pte);<br>    send_select_output(pte, pte->device->output, pte->device->volume, MUTE_ON);<br>       send_stop_timer(pte);<br>         if (sub->owner) {<br>          ast_queue_hold(sub->owner, NULL);<br>-         send_end_call(pte);<br>   }<br>     return;<br> }<br>@@ -2556,7 +2574,7 @@<br>    }<br> <br>  sub->moh = 0;<br>-     sub->subtype = SUB_REAL;<br>+  sub->holding = 0;<br>  send_favorite_short(sub->softkey, FAV_ICON_OFFHOOK_BLACK, pte);<br>    send_select_output(pte, pte->device->output, pte->device->volume, MUTE_OFF);<br>      send_start_timer(pte);<br>@@ -3356,12 +3374,12 @@<br> static void handle_key_fav(struct unistimsession *pte, char keycode)<br> {<br>    int keynum = keycode - KEY_FAV0;<br>-     struct unistim_subchannel *sub;<br>-<br>-   sub = get_sub(pte->device, SUB_REAL);<br>-<br>+  struct unistim_subchannel *sub, *sub_key = NULL;<br>+     sub = get_sub_holding(pte->device, SUB_REAL, 0);<br>+  <br>      /* Make an action on selected favorite key */<br>         if (!pte->device->ssub[keynum]) { /* Key have no assigned call */<br>+              sub = get_sub_holding(pte->device, SUB_REAL, 0);<br>           send_favorite_selected(FAV_LINE_ICON, pte);<br>           if (is_key_line(pte->device, keynum)) {<br>                    if (unistimdebug) {<br>@@ -3386,22 +3404,25 @@<br>                  key_favorite(pte, keycode);<br>           }<br>     } else {<br>-             sub = pte->device->ssub[keynum];<br>+               sub_key = pte->device->ssub[keynum];<br>            /* Favicon have assigned sub, activate it and put current on hold */<br>-         if (sub->subtype == SUB_REAL) {<br>-                   sub_hold(pte, sub);<br>+          if (sub_key->subtype == SUB_REAL && !sub_key->holding) {<br>+                       sub_hold(pte, sub_key);<br>                       show_main_page(pte);<br>-         } else if (sub->subtype == SUB_RING) {<br>-                    sub->softkey = keynum;<br>-                    handle_call_incoming(pte);<br>-           } else if (sub->subtype == SUB_ONHOLD) {<br>+          } else if (sub_key->subtype == SUB_REAL && sub_key->holding) { <br>+                        /* We are going to unhold line (we should put active line on hold, of any) */<br>                         if (pte->state == STATE_DIALPAGE){<br>                                 send_tone(pte, 0, 0);<br>                         }<br>-                    send_callerid_screen(pte, sub);<br>-                      sub_unhold(pte, sub);<br>+                        sub_hold(pte, sub);<br>+                  send_callerid_screen(pte, sub_key);<br>+                  sub_unhold(pte, sub_key);<br>                     pte->state = STATE_CALL;<br>-          }<br>+            } else if (sub_key->subtype == SUB_RING) {<br>+                        sub_hold(pte, sub);<br>+                  sub_key->softkey = keynum;<br>+                        handle_call_incoming(pte);<br>+           } <br>    }<br> }<br> <br>@@ -3470,8 +3491,13 @@<br>      case KEY_ONHOLD:<br>              if (!sub) {<br>                   if(pte->device->ssub[pte->device->selected]) {<br>-                           sub_hold(pte, pte->device->ssub[pte->device->selected]);<br>+                         sub = pte->device->ssub[pte->device->selected];<br>+                  } else {<br>+                             break;<br>                        }<br>+            }<br>+            if (sub->holding) {<br>+                       sub_unhold(pte, sub);<br>                 } else {<br>                      sub_hold(pte, sub);<br>           }<br>@@ -5429,6 +5455,7 @@<br>                                      }<br>                                     if (sub->owner) {<br>                                          /* Allocate additional channel if asterisk channel already here */<br>+                                           ast_log(LOG_WARNING, "Allocate ONHOLD channel!!!");<br>                                                 sub = unistim_alloc_sub(d, SUB_ONHOLD);<br>                                       }<br>                                     sub->ringvolume = -1;<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7880">change 7880</a>. To unsubscribe, 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/7880"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ib1e04e482e7c8939607a42d7fddacc07e26e14d4 </div>
<div style="display:none"> Gerrit-Change-Number: 7880 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Igor Goncharovsky <igor.goncharovsky@gmail.com> </div>