From c75a71d9b6012c46743099b53d172ad46e6f41d2 Mon Sep 17 00:00:00 2001 From: Satish Kodishala Date: Wed, 22 Jun 2016 14:22:41 +0530 Subject: [PATCH] AG: CLCC response can contain non-ATD characters 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 | 12 ++++++++++++ bta/sys/utl.cc | 33 +++++++++++++++++++++++---------- btif/src/btif_hf.cc | 26 ++++++++++++++++++-------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/bta/include/utl.h b/bta/include/utl.h index 2b988ab7b..c09aa2415 100644 --- a/bta/include/utl.h +++ b/bta/include/utl.h @@ -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 diff --git a/bta/sys/utl.cc b/bta/sys/utl.cc index 61b8d437a..5832b11a1 100644 --- a/bta/sys/utl.cc +++ b/bta/sys/utl.cc @@ -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; } diff --git a/btif/src/btif_hf.cc b/btif/src/btif_hf.cc index e75a2456e..4f8f04723 100644 --- a/btif/src/btif_hf.cc +++ b/btif/src/btif_hf.cc @@ -34,6 +34,7 @@ #include #include +#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); -- 2.11.0