Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e07b3281 authored by Satish Kodishala's avatar Satish Kodishala Committed by Marie Janssen
Browse files

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
parent d4265ddc
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -135,6 +135,18 @@ extern bool utl_set_device_class(tBTA_UTL_COD *p_cod, uint8_t cmd);
*******************************************************************************/
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
+23 −10
Original line number Diff line number Diff line
@@ -246,6 +246,25 @@ bool utl_isintstr(const char *p_s)
    return true;
}

/*******************************************************************************
**
** 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
@@ -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;
}

+18 −8
Original line number Diff line number Diff line
@@ -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);