OSDN Git Service

AG: CLCC response can contain non-ATD characters
authorSatish Kodishala <skodisha@codeaurora.org>
Wed, 22 Jun 2016 08:52:41 +0000 (14:22 +0530)
committerMarie Janssen <jamuraa@google.com>
Tue, 1 Nov 2016 22:37:02 +0000 (15:37 -0700)
Test case:
1. Connect Plantronics backbeat PRO headset.
2. Initiate outgoing call from phone.
3. Accept the call from remote side and terminate call.
4. Try to redial from headset and observe

Failure:
AG is sending error for redial request from BT headset.

Root cause:
Sometimes, the number in CLCC response has "-".
Repeated from the headset, the ATD string has "-"
which is not allowed in the dial string for ATD and
errors.

Fix:
 * Sanitize CLCC response to only include valid ATD characters.
 * Accept "-" in ATD because it works for us.

Change-Id: I854165c7da295f428852c829543eb4fc18455d91

bta/include/utl.h
bta/sys/utl.cc
btif/src/btif_hf.cc

index 2b988ab..c09aa24 100644 (file)
@@ -137,6 +137,18 @@ extern bool utl_isintstr(const char *p_s);
 
 /*******************************************************************************
 **
+** Function         utl_isdialchar
+**
+** Description      This utility function checks if the given character
+**                  is an acceptable dial digit
+**
+** Returns          true if successful, Otherwise false
+**
+*******************************************************************************/
+extern bool utl_isdialchar(const char d);
+
+/*******************************************************************************
+**
 ** Function         utl_isdialstr
 **
 ** Description      This utility function checks if the given string contains
index 61b8d43..5832b11 100644 (file)
@@ -248,6 +248,25 @@ bool utl_isintstr(const char *p_s)
 
 /*******************************************************************************
 **
+** Function         utl_isdialchar
+**
+** Description      This utility function checks if the given character
+**                  is an acceptable dial digit
+**
+** Returns          true if successful, Otherwise false
+**
+*******************************************************************************/
+bool utl_isdialchar(const char d)
+{
+    return (((d >= '0') && (d <= '9'))
+            || (d == '*') || (d == '+') || (d == '#') || (d == ';')
+            || ((d >= 'A') && (d <= 'C'))
+            || ((d == 'p') || (d == 'P')
+            || (d == 'w') || (d == 'W')));
+}
+
+/*******************************************************************************
+**
 ** Function         utl_isdialstr
 **
 ** Description      This utility function checks if the given string contains
@@ -259,18 +278,12 @@ bool utl_isintstr(const char *p_s)
 *******************************************************************************/
 bool utl_isdialstr(const char *p_s)
 {
-    uint16_t i = 0;
-
-    for(i=0; p_s[i] != 0; i++)
-    {
-        if(!(((p_s[i] >= '0') && (p_s[i] <= '9'))
-            || (p_s[i] == '*') || (p_s[i] == '+') || (p_s[i] == '#') || (p_s[i] == ';')
-            || ((p_s[i] >= 'A') && (p_s[i] <= 'C'))
-            || ((p_s[i] == 'p') || (p_s[i] == 'P')
-            || (p_s[i] == 'w') || (p_s[i] == 'W'))))
+    for (uint16_t i = 0; p_s[i] != 0; i++) {
+        // include chars not in spec that work sent by some headsets.
+        if(!(utl_isdialchar(p_s[i])
+            || (p_s[i] == '-')))
             return false;
     }
-
     return true;
 }
 
index e75a245..4f8f047 100644 (file)
@@ -34,6 +34,7 @@
 #include <hardware/bluetooth.h>
 #include <hardware/bt_hf.h>
 
+#include "bta/include/utl.h"
 #include "bta_ag_api.h"
 #include "btcore/include/bdaddr.h"
 #include "btif_common.h"
@@ -1176,7 +1177,6 @@ static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
 
   if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX)) {
     tBTA_AG_RES_DATA ag_res;
-
     memset(&ag_res, 0, sizeof(ag_res));
 
     /* Format the response */
@@ -1186,15 +1186,25 @@ static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
       BTIF_TRACE_EVENT(
           "clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
           index, dir, state, mode, number, type);
-      int xx = snprintf(ag_res.str, sizeof(ag_res.str), "%d,%d,%d,%d,%d", index,
-                        dir, state, mode, mpty);
+      int res_strlen = snprintf(ag_res.str, sizeof(ag_res.str),
+                                "%d,%d,%d,%d,%d", index, dir, state, mode,
+                                mpty);
 
       if (number) {
-        size_t rem_bytes = sizeof(ag_res.str) - xx;
-        if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
-          snprintf(&ag_res.str[xx], rem_bytes, ",\"+%s\",%d", number, type);
-        else
-          snprintf(&ag_res.str[xx], rem_bytes, ",\"%s\",%d", number, type);
+        size_t rem_bytes = sizeof(ag_res.str) - res_strlen;
+        char dialnum[sizeof(ag_res.str)];
+        size_t newidx = 0;
+        if (type == BTHF_CALL_ADDRTYPE_INTERNATIONAL && *number != '+') {
+          dialnum[newidx++] = '+';
+        }
+        for (size_t i = 0; number[i] != 0; i++) {
+          if (utl_isdialchar(number[i])) {
+            dialnum[newidx++] = number[i];
+          }
+        }
+        dialnum[newidx] = 0;
+        snprintf(&ag_res.str[res_strlen], rem_bytes, ",\"%s\",%d", dialnum,
+                 type);
       }
     }
     BTA_AgResult(btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res);