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

Commit 8ee0d82f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "HFPClient: HF Indicators support"

parents a1b033e5 e1ecc6cd
Loading
Loading
Loading
Loading
+133 −17
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@
#define BTA_HF_CLIENT_INDICATOR_CALLSETUP "callsetup"
#define BTA_HF_CLIENT_INDICATOR_CALLHELD "callheld"

/* BIND parse mode */
#define BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND 0
#define BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND 1

#define MIN(a, b)           \
  ({                        \
    __typeof__(a) _a = (a); \
@@ -147,7 +151,7 @@ static void bta_hf_client_at_resp_timer_cback(void* data) {
  } else {
    APPL_TRACE_ERROR("HFPClient: AT response timeout, disconnecting");

    tBTA_HF_CLIENT_DATA msg;
    tBTA_HF_CLIENT_DATA msg = {};
    msg.hdr.layer_specific = client_cb->handle;
    bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
  }
@@ -391,6 +395,24 @@ static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb,
  client_cb->chld_features |= mask;
}

static void bta_hf_client_handle_bind_read_supported_ind(
    tBTA_HF_CLIENT_CB* client_cb, int indicator_id) {
  APPL_TRACE_DEBUG("%s: %d", __func__, indicator_id);

  client_cb->peer_hf_indicators.insert(indicator_id);
}

static void bta_hf_client_handle_bind_read_enabled_ind(
    tBTA_HF_CLIENT_CB* client_cb, int indicator_id, bool enable) {
  APPL_TRACE_DEBUG("%s: %d", __func__, indicator_id);

  if (enable) {
    client_cb->enabled_hf_indicators.insert(indicator_id);
  } else {
    client_cb->enabled_hf_indicators.erase(indicator_id);
  }
}

static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb,
                                      uint32_t index, uint32_t value) {
  int8_t realind = -1;
@@ -983,6 +1005,46 @@ static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb,
  return buffer;
}

static char* bta_hf_client_parse_bind(tBTA_HF_CLIENT_CB* client_cb,
                                      char* buffer) {
  AT_CHECK_EVENT(buffer, "+BIND:");

  uint8_t mode = BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND;

  int idx = -1;

  while (*buffer != 0) {
    switch (*buffer) {
      case '(':
        mode = BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND;
        break;
      case ')':
        break;
      case '0':
      case '1':
      case '2':
        if (mode == BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND) {
          // +BIND: (id0, id1, ...)
          bta_hf_client_handle_bind_read_supported_ind(client_cb,
                                                       (*buffer - '0'));
        } else if (idx == -1) {
          // +BIND: [id]...
          idx = *buffer - '0';
        } else {
          // +BIND: ...[status]
          bta_hf_client_handle_bind_read_enabled_ind(client_cb, idx,
                                                     *buffer - '0');
        }
        break;
      default:
        break;
    }
    buffer++;
  }

  return buffer;
}

static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb,
                                      char* buffer) {
  uint32_t index, value;
@@ -1497,9 +1559,10 @@ static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
    bta_hf_client_parse_ccwa,      bta_hf_client_parse_cops,
    bta_hf_client_parse_binp,      bta_hf_client_parse_clcc,
    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_rejectlisted, bta_hf_client_process_unknown};
    bta_hf_client_parse_bind,      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_rejectlisted,
    bta_hf_client_process_unknown};

/* calculate supported event list length */
static const uint16_t bta_hf_client_parser_cb_count =
@@ -1568,7 +1631,7 @@ static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
          "HFPCient: could not skip unknown AT event, disconnecting");
      bta_hf_client_at_reset(client_cb);

      tBTA_HF_CLIENT_DATA msg;
      tBTA_HF_CLIENT_DATA msg = {};
      msg.hdr.layer_specific = client_cb->handle;
      bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
      return;
@@ -1631,7 +1694,7 @@ void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,

        bta_hf_client_at_reset(client_cb);

        tBTA_HF_CLIENT_DATA msg;
        tBTA_HF_CLIENT_DATA msg = {};
        msg.hdr.layer_specific = client_cb->handle;
        bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
        return;
@@ -1755,6 +1818,54 @@ void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
  bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
}

void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step) {
  std::string buf;
  tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;

  APPL_TRACE_DEBUG("%s", __func__);

  switch (step) {
    case 0:  // List HF supported indicators
      // TODO: Add flags to determine enabled HF features
      buf = "AT+BIND=1,2\r";
      cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;
      break;
    case 1:  // Read AG supported indicators
      buf = "AT+BIND=?\r";
      cmd = BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND;
      break;
    case 2:  // Read AG enabled/disabled status of indicators
      buf = "AT+BIND?\r";
      cmd = BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND;
      break;
    default:
      break;
  }
  bta_hf_client_send_at(client_cb, cmd, buf.c_str(), buf.size());
}

void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id,
                                int indicator_value) {
  char buf[32];
  tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIEV;

  if ((client_cb->peer_features & BTA_HF_CLIENT_FEAT_HF_IND) == 0) {
    APPL_TRACE_ERROR("%s peer does not support HF Indicators", __func__);
    return;
  }

  if (client_cb->enabled_hf_indicators.count(indicator_id) <= 0) {
    APPL_TRACE_ERROR("%s HF indicators %d is disabled", __func__, indicator_id);
    return;
  }

  APPL_TRACE_DEBUG("%s", __func__);

  int len = sprintf(buf, "AT+BIEV=%d,%d\r", indicator_id, indicator_value);

  bta_hf_client_send_at(client_cb, cmd, buf, len);
}

void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
  const char* buf;

@@ -2107,6 +2218,11 @@ void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
      bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
                                 p_val->uint32_val2);
      break;
    case BTA_HF_CLIENT_AT_CMD_BIEV:
      /* expects ascii code for command */
      bta_hf_client_send_at_biev(client_cb, p_val->uint32_val1,
                                 p_val->uint32_val2);
      break;
    case BTA_HF_CLIENT_AT_CMD_BCC:
      bta_hf_client_send_at_bcc(client_cb);
      break;
+16 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
 ******************************************************************************/

#include <cstdint>
#include <unordered_set>

#include "bta/hf_client/bta_hf_client_at.h"
#include "bta/include/bta_hf_client_api.h"
@@ -98,6 +99,10 @@ enum {
  BTA_HF_CLIENT_AT_CNUM,
  BTA_HF_CLIENT_AT_NREC,
  BTA_HF_CLIENT_AT_BINP,
  BTA_HF_CLIENT_AT_BIND_SET_IND,
  BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND,
  BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND,
  BTA_HF_CLIENT_AT_BIEV,
  BTA_HF_CLIENT_AT_VENDOR_SPECIFIC,
};

@@ -181,6 +186,10 @@ typedef struct {
  uint8_t state;              /* state machine state */
  bool is_allocated;          /* if the control block is already allocated */
  alarm_t* collision_timer;   /* Collision timer */
  std::unordered_set<int>
      peer_hf_indicators; /* peer supported hf indicator indices (HFP1.7) */
  std::unordered_set<int>
      enabled_hf_indicators; /* enabled hf indicator indices (HFP1.7) */
} tBTA_HF_CLIENT_CB;

typedef struct {
@@ -267,6 +276,9 @@ extern void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb,
                                       bool activate);
extern void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
                                       uint32_t idx);
extern void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step);
extern void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int ind_id,
                                       int value);
extern void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb,
                                       bool activate);
extern void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb,
+30 −3
Original line number Diff line number Diff line
@@ -297,8 +297,13 @@ void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
  // Free any memory we need to explicity release
  alarm_free(client_cb->collision_timer);

  // release unique pointers
  client_cb->enabled_hf_indicators.clear();
  client_cb->peer_hf_indicators.clear();

  // Memset the rest of the block
  memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
  // memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
  *client_cb = {};

  // Re allocate any variables required
  client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
@@ -834,6 +839,9 @@ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
      if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
          bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
        bta_hf_client_send_at_chld(client_cb, '?', 0);
      } else if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
                 client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
        bta_hf_client_send_at_bind(client_cb, 0);
      } else {
        tBTA_HF_CLIENT_DATA msg;
        msg.hdr.layer_specific = client_cb->handle;
@@ -842,13 +850,32 @@ void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
      }
      break;

    case BTA_HF_CLIENT_AT_CHLD: {
    case BTA_HF_CLIENT_AT_CHLD:
      if (bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_HF_IND &&
          client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) {
        bta_hf_client_send_at_bind(client_cb, 0);
      } else {
        tBTA_HF_CLIENT_DATA msg;
        msg.hdr.layer_specific = client_cb->handle;
        bta_hf_client_svc_conn_open(&msg);
        send_post_slc_cmd(client_cb);
      break;
      }
      break;

    case BTA_HF_CLIENT_AT_BIND_SET_IND:
      bta_hf_client_send_at_bind(client_cb, 1);
      break;

    case BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND:
      bta_hf_client_send_at_bind(client_cb, 2);
      break;

    case BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND:
      tBTA_HF_CLIENT_DATA msg;
      msg.hdr.layer_specific = client_cb->handle;
      bta_hf_client_svc_conn_open(&msg);
      send_post_slc_cmd(client_cb);
      break;

    default: {
      /* If happen there is a bug in SLC creation procedure... */
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#define BTA_HF_CLIENT_PEER_ECC 0x00000080 /* Enhanced Call Control */
#define BTA_HF_CLIENT_PEER_EXTERR 0x00000100 /* Extended error codes */
#define BTA_HF_CLIENT_PEER_CODEC 0x00000200  /* Codec Negotiation */
#define BTA_HF_CLIENT_PEER_HF_IND 0x00000400 /* HF Indicators */
#define BTA_HF_CLIENT_PEER_ESCO_S4 0x00000800 /* ESCO S4 link setting */

typedef uint16_t tBTA_HF_CLIENT_PEER_FEAT;
@@ -65,6 +66,7 @@ typedef uint16_t tBTA_HF_CLIENT_PEER_FEAT;
#define BTA_HF_CLIENT_FEAT_ECS 0x00000020   /* Enhanced Call Status */
#define BTA_HF_CLIENT_FEAT_ECC 0x00000040   /* Enhanced Call Control */
#define BTA_HF_CLIENT_FEAT_CODEC 0x00000080 /* Codec Negotiation */
#define BTA_HF_CLIENT_FEAT_HF_IND 0x00000100  /* HF Indicators */
#define BTA_HF_CLIENT_FEAT_ESCO_S4 0x00000200 /* ESCO S4 link setting */

/* HFP HF extended call handling - masks not related to any spec */
@@ -169,6 +171,7 @@ typedef uint8_t tBTA_HF_CLIENT_IND_TYPE;
#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
#define BTA_HF_CLIENT_AT_CMD_BIEV 17

typedef uint8_t tBTA_HF_CLIENT_AT_CMD_TYPE;