<p>Kevin Harwell <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14341">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_mobile: Add smoother to make SIP/RTP endpoints happy.<br><br>In contrast to RFC 3551, section 4.2, several SIP/RTP clients misbehave<br>severly (up to crashing). This patch adds another smoother for the audio<br>received via bt. Therefore the audio frames sent to the core will be<br>CHANNEL_FRAME_SIZE.<br><br>ASTERISK-28832 #close<br><br>Change-Id: Ic5f9e2f35868ae59cc9356afbd1388b779a1267f<br>---<br>M addons/chan_mobile.c<br>1 file changed, 39 insertions(+), 24 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/addons/chan_mobile.c b/addons/chan_mobile.c</span><br><span>index 427977d..240c2d4 100644</span><br><span>--- a/addons/chan_mobile.c</span><br><span>+++ b/addons/chan_mobile.c</span><br><span>@@ -132,7 +132,8 @@</span><br><span>      int rfcomm_socket;                              /* rfcomm socket descriptor */</span><br><span>       char rfcomm_buf[256];</span><br><span>        char io_buf[CHANNEL_FRAME_SIZE + AST_FRIENDLY_OFFSET];</span><br><span style="color: hsl(0, 100%, 40%);">-  struct ast_smoother *smoother;                  /* our smoother, for making 48 byte frames */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_smoother *bt_out_smoother;                   /* our bt_out_smoother, for making 48 byte frames */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ast_smoother *bt_in_smoother;                    /* our smoother, for making "normal" CHANNEL_FRAME_SIZEed byte frames */</span><br><span>   int sco_socket;                                 /* sco socket descriptor */</span><br><span>  pthread_t monitor_thread;                       /* monitor thread handle */</span><br><span>  int timeout;                                    /*!< used to set the timeout for rfcomm data (may be used in the future) */</span><br><span>@@ -856,7 +857,8 @@</span><br><span>         else</span><br><span>                 pvt->do_alignment_detection = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ast_smoother_reset(pvt->smoother, DEVICE_FRAME_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_smoother_reset(pvt->bt_out_smoother, DEVICE_FRAME_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_smoother_reset(pvt->bt_in_smoother, CHANNEL_FRAME_SIZE);</span><br><span>      ast_dsp_digitreset(pvt->dsp);</span><br><span> </span><br><span>         chn = ast_channel_alloc(1, state,</span><br><span>@@ -1131,23 +1133,27 @@</span><br><span>  pvt->fr.delivery.tv_usec = 0;</span><br><span>     pvt->fr.data.ptr = pvt->io_buf + AST_FRIENDLY_OFFSET;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if ((r = read(pvt->sco_socket, pvt->fr.data.ptr, DEVICE_FRAME_SIZE)) == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (errno != EAGAIN && errno != EINTR) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_debug(1, "[%s] read error %d, going to wait for new connection\n", pvt->id, errno);</span><br><span style="color: hsl(0, 100%, 40%);">-                    close(pvt->sco_socket);</span><br><span style="color: hsl(0, 100%, 40%);">-                      pvt->sco_socket = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_channel_set_fd(ast, 0, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+       do {</span><br><span style="color: hsl(120, 100%, 40%);">+          if ((r = read(pvt->sco_socket, pvt->fr.data.ptr, DEVICE_FRAME_SIZE)) == -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (errno != EAGAIN && errno != EINTR) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_debug(1, "[%s] read error %d, going to wait for new connection\n", pvt->id, errno);</span><br><span style="color: hsl(120, 100%, 40%);">+                          close(pvt->sco_socket);</span><br><span style="color: hsl(120, 100%, 40%);">+                            pvt->sco_socket = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_channel_set_fd(ast, 0, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto e_return;</span><br><span>               }</span><br><span style="color: hsl(0, 100%, 40%);">-               goto e_return;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   pvt->fr.datalen = r;</span><br><span style="color: hsl(0, 100%, 40%);">- pvt->fr.samples = r / 2;</span><br><span style="color: hsl(120, 100%, 40%);">+           pvt->fr.datalen = r;</span><br><span style="color: hsl(120, 100%, 40%);">+               pvt->fr.samples = r / 2;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (pvt->do_alignment_detection)</span><br><span style="color: hsl(0, 100%, 40%);">-             do_alignment_detection(pvt, pvt->fr.data.ptr, r);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (pvt->do_alignment_detection)</span><br><span style="color: hsl(120, 100%, 40%);">+                   do_alignment_detection(pvt, pvt->fr.data.ptr, r);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        fr = ast_dsp_process(ast, pvt->dsp, &pvt->fr);</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_smoother_feed(pvt->bt_in_smoother, &pvt->fr);</span><br><span style="color: hsl(120, 100%, 40%);">+           fr = ast_smoother_read(pvt->bt_in_smoother);</span><br><span style="color: hsl(120, 100%, 40%);">+       } while (fr == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ fr = ast_dsp_process(ast, pvt->dsp, fr);</span><br><span> </span><br><span>      ast_mutex_unlock(&pvt->lock);</span><br><span> </span><br><span>@@ -1174,9 +1180,9 @@</span><br><span>             CHANNEL_DEADLOCK_AVOIDANCE(ast);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_smoother_feed(pvt->smoother, frame);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_smoother_feed(pvt->bt_out_smoother, frame);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  while ((f = ast_smoother_read(pvt->smoother))) {</span><br><span style="color: hsl(120, 100%, 40%);">+   while ((f = ast_smoother_read(pvt->bt_out_smoother))) {</span><br><span>           sco_write(pvt->sco_socket, f->data.ptr, f->datalen);</span><br><span>        }</span><br><span> </span><br><span>@@ -4530,16 +4536,22 @@</span><br><span>      pvt->ring_sched_id = -1;</span><br><span>  pvt->has_sms = 1;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        /* setup the smoother */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!(pvt->smoother = ast_smoother_new(DEVICE_FRAME_SIZE))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_log(LOG_ERROR, "Skipping device %s. Error setting up frame smoother.\n", cat);</span><br><span style="color: hsl(120, 100%, 40%);">+  /* setup the bt_out_smoother */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!(pvt->bt_out_smoother = ast_smoother_new(DEVICE_FRAME_SIZE))) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_log(LOG_ERROR, "Skipping device %s. Error setting up frame bt_out_smoother.\n", cat);</span><br><span>          goto e_free_pvt;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* setup the bt_in_smoother */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!(pvt->bt_in_smoother = ast_smoother_new(CHANNEL_FRAME_SIZE))) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_log(LOG_ERROR, "Skipping device %s. Error setting up frame bt_in_smoother.\n", cat);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto e_free_bt_out_smoother;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* setup the dsp */</span><br><span>  if (!(pvt->dsp = ast_dsp_new())) {</span><br><span>                ast_log(LOG_ERROR, "Skipping device %s. Error setting up dsp for dtmf detection.\n", cat);</span><br><span style="color: hsl(0, 100%, 40%);">-            goto e_free_smoother;</span><br><span style="color: hsl(120, 100%, 40%);">+         goto e_free_bt_in_smoother;</span><br><span>  }</span><br><span> </span><br><span>        /* setup the scheduler */</span><br><span>@@ -4599,8 +4611,10 @@</span><br><span>   ast_sched_context_destroy(pvt->sched);</span><br><span> e_free_dsp:</span><br><span>     ast_dsp_free(pvt->dsp);</span><br><span style="color: hsl(0, 100%, 40%);">-e_free_smoother:</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_smoother_free(pvt->smoother);</span><br><span style="color: hsl(120, 100%, 40%);">+e_free_bt_in_smoother:</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_smoother_free(pvt->bt_in_smoother);</span><br><span style="color: hsl(120, 100%, 40%);">+e_free_bt_out_smoother:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_smoother_free(pvt->bt_out_smoother);</span><br><span> e_free_pvt:</span><br><span>   ast_free(pvt);</span><br><span> e_return:</span><br><span>@@ -4732,7 +4746,8 @@</span><br><span>                  ast_free(pvt->hfp);</span><br><span>               }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           ast_smoother_free(pvt->smoother);</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_smoother_free(pvt->bt_out_smoother);</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_smoother_free(pvt->bt_in_smoother);</span><br><span>           ast_dsp_free(pvt->dsp);</span><br><span>           ast_sched_context_destroy(pvt->sched);</span><br><span>            ast_free(pvt);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14341">change 14341</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/+/14341"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 17 </div>
<div style="display:none"> Gerrit-Change-Id: Ic5f9e2f35868ae59cc9356afbd1388b779a1267f </div>
<div style="display:none"> Gerrit-Change-Number: 14341 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Peter Turczak <peter@turczak.de> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>