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

Commit 7a2b0850 authored by Deqiang Chen's avatar Deqiang Chen Committed by deqiang chen
Browse files

Support vendor AT command and response for Hfp Client in bt stack

Add necessary interface in system/bt to support sending vendor AT
command. Also passing unknow events(vendor specific events) up for
further processing.

Bug: 132813146

Test: local test with kichensink to send vendor at command and receive
response. Also run unit test
atest BluetoothHeadsetClientStateMachineTest

Change-Id: Id460eaf00be269d15e6baf0fd30bdbf8e57df78d
parent dbda8935
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ interface IBluetoothHeadsetClient {
    boolean disconnectAudio(in BluetoothDevice device);
    void setAudioRouteAllowed(in BluetoothDevice device, boolean allowed);
    boolean getAudioRouteAllowed(in BluetoothDevice device);
    boolean sendVendorAtCommand(in BluetoothDevice device, int vendorId, String atCommand);

    Bundle getCurrentAgFeatures(in BluetoothDevice device);
}
+66 −4
Original line number Diff line number Diff line
@@ -724,9 +724,7 @@ void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx,
 ******************************************************************************/
void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
                        uint16_t service) {
  tBTA_HF_CLIENT evt;

  memset(&evt, 0, sizeof(evt));
  tBTA_HF_CLIENT evt = {};

  evt.cnum.service = service;
  strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
@@ -736,6 +734,18 @@ void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
  bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
}

void bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB* client_cb,
                                    const char* evt_buffer) {
  tBTA_HF_CLIENT evt = {};

  strlcpy(evt.unknown.event_string, evt_buffer,
          BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1);
  evt.unknown.event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN] = '\0';

  evt.unknown.bd_addr = client_cb->peer_addr;
  bta_hf_client_app_callback(BTA_HF_CLIENT_UNKNOWN_EVT, &evt);
}

/*******************************************************************************
 *
 * Function         bta_hf_client_binp
@@ -1436,6 +1446,36 @@ static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb,
  return buffer;
}

static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb,
                                           char* buffer) {
  char* start = strstr(buffer, "\r\n");
  if (start == NULL) {
    return NULL;
  }
  start += sizeof("\r\n") - 1;

  char* end = strstr(start, "\r\n");
  if (end == NULL) {
    return NULL;
  }

  int evt_size = end - start + 1;

  char tmp_buf[BTA_HF_CLIENT_UNKOWN_EVENT_LEN];
  if (evt_size < BTA_HF_CLIENT_UNKOWN_EVENT_LEN) {
    strlcpy(tmp_buf, start, evt_size);
    bta_hf_client_unknown_response(client_cb, tmp_buf);
    AT_CHECK_RN(end);
  } else {
    APPL_TRACE_ERROR("%s: exceed event buffer size. (%d, %d)", __func__,
                     evt_size, BTA_HF_CLIENT_UNKOWN_EVENT_LEN);
  }

  APPL_TRACE_DEBUG("%s: %s", __func__, buffer);

  return end;
}

/******************************************************************************
 *       SUPPORTED EVENT MESSAGES
 ******************************************************************************/
@@ -1461,7 +1501,7 @@ static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
    bta_hf_client_parse_cnum,        bta_hf_client_parse_btrh,
    bta_hf_client_parse_busy,        bta_hf_client_parse_delayed,
    bta_hf_client_parse_no_carrier,  bta_hf_client_parse_no_answer,
    bta_hf_client_parse_blacklisted, bta_hf_client_skip_unknown};
    bta_hf_client_parse_blacklisted, bta_hf_client_process_unknown};

/* calculate supported event list length */
static const uint16_t bta_hf_client_parser_cb_count =
@@ -1996,6 +2036,25 @@ void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
  bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
}

void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb,
                                               const char* str) {
  char buf[BTA_HF_CLIENT_AT_MAX_LEN];

  APPL_TRACE_DEBUG("%s", __func__);

  int at_len = snprintf(buf, sizeof(buf), "AT%s", str);

  if (at_len < 1) {
    APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
    return;
  }

  buf[at_len - 1] = '\r';

  bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VENDOR_SPECIFIC, buf,
                        at_len);
}

void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
  alarm_free(client_cb->at_cb.resp_timer);
  alarm_free(client_cb->at_cb.hold_timer);
@@ -2087,6 +2146,9 @@ void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
    case BTA_HF_CLIENT_AT_CMD_NREC:
      bta_hf_client_send_at_nrec(client_cb);
      break;
    case BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD:
      bta_hf_client_send_at_vendor_specific_cmd(client_cb, p_val->str);
      break;
    default:
      APPL_TRACE_ERROR("Default case");
      snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ enum {
  BTA_HF_CLIENT_AT_CNUM,
  BTA_HF_CLIENT_AT_NREC,
  BTA_HF_CLIENT_AT_BINP,
  BTA_HF_CLIENT_AT_VENDOR_SPECIFIC,
};

/*****************************************************************************
+12 −0
Original line number Diff line number Diff line
@@ -119,6 +119,9 @@ typedef uint8_t tBTA_HF_CLIENT_AT_RESULT_TYPE;
                                     */
#define BTA_HF_CLIENT_BINP_EVT 20 /* binp number event */
#define BTA_HF_CLIENT_RING_INDICATION 21 /* HF Client ring indication */

#define BTA_HF_CLIENT_UNKNOWN_EVT 22 /* Unknown or vendor specific Event */

#define BTA_HF_CLIENT_DISABLE_EVT 30     /* HF Client disabled */

typedef uint8_t tBTA_HF_CLIENT_EVT;
@@ -159,6 +162,7 @@ typedef uint8_t tBTA_HF_CLIENT_IND_TYPE;
#define BTA_HF_CLIENT_AT_CMD_BINP 13
#define BTA_HF_CLIENT_AT_CMD_BLDN 14
#define BTA_HF_CLIENT_AT_CMD_NREC 15
#define BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD 16

typedef uint8_t tBTA_HF_CLIENT_AT_CMD_TYPE;

@@ -234,6 +238,13 @@ typedef struct {
  uint16_t value;
} tBTA_HF_CLIENT_VAL;

/* data associated with BTA_HF_CLIENT_UNKNOWN_EVT event */
#define BTA_HF_CLIENT_UNKOWN_EVENT_LEN 32
typedef struct {
  RawAddress bd_addr;
  char event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1];
} tBTA_HF_CLIENT_UNKNOWN;

/* union of data associated with AG callback */
typedef union {
  // Common BD ADDR field for all tyepdefs
@@ -248,6 +259,7 @@ typedef union {
  tBTA_HF_CLIENT_AT_RESULT result;
  tBTA_HF_CLIENT_CLCC clcc;
  tBTA_HF_CLIENT_CNUM cnum;
  tBTA_HF_CLIENT_UNKNOWN unknown;
} tBTA_HF_CLIENT;

typedef uint32_t tBTA_HF_CLIENT_FEAT;
+4 −0
Original line number Diff line number Diff line
@@ -999,6 +999,10 @@ static void btif_hf_client_upstreams_evt(uint16_t event, char* p_param) {
    case BTA_HF_CLIENT_RING_INDICATION:
      HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb, &cb->peer_bda);
      break;
    case BTA_HF_CLIENT_UNKNOWN_EVT:
      HAL_CBACK(bt_hf_client_callbacks, unknown_event_cb, &cb->peer_bda,
                p_data->unknown.event_string);
      break;
    default:
      BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
      break;
Loading