OSDN Git Service

HFP: Report AT+BIA command to upper layer
authorJack He <siyuanh@google.com>
Thu, 5 Apr 2018 22:39:27 +0000 (15:39 -0700)
committerJack He <siyuanh@google.com>
Fri, 6 Apr 2018 23:58:45 +0000 (16:58 -0700)
* Report AT+BIA command, AG indicator activation command, to upper layer
  so that upper layer can decide on whether or not to subscribe to these
  indicators

Bug: 77655992
Test: make

Change-Id: Ic330d6784c5edf20683cbfedda3fa54525878ce8

bta/ag/bta_ag_cmd.cc
bta/include/bta_ag_api.h
btif/src/btif_hf.cc
btif/src/btif_util.cc
include/hardware/bluetooth_headset_callbacks.h

index b5a420b..c162509 100644 (file)
@@ -63,7 +63,6 @@ enum {
   BTA_AG_LOCAL_EVT_CMER,
   BTA_AG_LOCAL_EVT_BRSF,
   BTA_AG_LOCAL_EVT_CMEE,
-  BTA_AG_LOCAL_EVT_BIA,
   BTA_AG_LOCAL_EVT_BCC,
 };
 
@@ -105,7 +104,7 @@ const tBTA_AG_AT_CMD bta_ag_hfp_cmd[] = {
     {"+COPS", BTA_AG_AT_COPS_EVT, BTA_AG_AT_READ | BTA_AG_AT_SET, BTA_AG_AT_STR,
      0, 0},
     {"+CMEE", BTA_AG_LOCAL_EVT_CMEE, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 1},
-    {"+BIA", BTA_AG_LOCAL_EVT_BIA, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 20},
+    {"+BIA", BTA_AG_AT_BIA_EVT, BTA_AG_AT_SET, BTA_AG_AT_STR, 0, 20},
     {"+CBC", BTA_AG_AT_CBC_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0, 100},
     {"+BCC", BTA_AG_LOCAL_EVT_BCC, BTA_AG_AT_NONE, BTA_AG_AT_STR, 0, 0},
     {"+BCS", BTA_AG_AT_BCS_EVT, BTA_AG_AT_SET, BTA_AG_AT_INT, 0,
@@ -842,7 +841,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
   val.hdr.handle = bta_ag_scb_to_idx(p_scb);
   val.hdr.app_id = p_scb->app_id;
   val.hdr.status = BTA_AG_SUCCESS;
-  val.num = int_arg;
+  val.num = static_cast<uint32_t>(int_arg);
   val.bd_addr = p_scb->peer_addr;
   strlcpy(val.str, p_arg, sizeof(val.str));
 
@@ -853,7 +852,9 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
    * callback is NOT invoked.
    */
   tBTA_AG_EVT event = 0;
-  if (cmd < BTA_AG_LOCAL_EVT_FIRST) event = cmd;
+  if (cmd < BTA_AG_LOCAL_EVT_FIRST) {
+    event = static_cast<tBTA_AG_EVT>(cmd);
+  }
 
   switch (cmd) {
     case BTA_AG_AT_A_EVT:
@@ -1140,32 +1141,37 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
       event = 0;
       break;
 
-    case BTA_AG_LOCAL_EVT_BIA:
-      /* don't call callback */
-      event = 0;
-
+    case BTA_AG_AT_BIA_EVT:
       bia_masked_out = p_scb->bia_masked_out;
 
       /* Parse the indicator mask */
       for (i = 0, ind_id = 1; (val.str[i] != 0) && (ind_id <= 20);
            i++, ind_id++) {
-        if (val.str[i] == ',') continue;
+        if (val.str[i] == ',') {
+          continue;
+        }
 
-        if (val.str[i] == '0')
+        if (val.str[i] == '0') {
           bia_masked_out |= ((uint32_t)1 << ind_id);
-        else if (val.str[i] == '1')
+        } else if (val.str[i] == '1') {
           bia_masked_out &= ~((uint32_t)1 << ind_id);
-        else
+        } else {
           break;
+        }
 
         i++;
-        if ((val.str[i] == 0) || (val.str[i] != ',')) break;
+        if (val.str[i] != ',') {
+          break;
+        }
       }
       if (val.str[i] == 0) {
         p_scb->bia_masked_out = bia_masked_out;
+        val.num = bia_masked_out;
         bta_ag_send_ok(p_scb);
-      } else
+      } else {
+        event = 0;
         bta_ag_send_error(p_scb, BTA_AG_ERR_INVALID_INDEX);
+      }
       break;
 
     case BTA_AG_AT_CNUM_EVT:
index d6ec916..6843dbf 100644 (file)
@@ -316,6 +316,7 @@ struct tBTA_AG_RES_DATA {
 #define BTA_AG_AT_BCS_EVT 27  /* Codec select */
 #define BTA_AG_AT_BIND_EVT 28 /* HF indicator */
 #define BTA_AG_AT_BIEV_EVT 29 /* HF indicator updates from peer */
+#define BTA_AG_AT_BIA_EVT 32  /* AG indicator activation event from peer */
 
 typedef uint8_t tBTA_AG_EVT;
 
@@ -359,7 +360,7 @@ typedef struct {
   tBTA_AG_HDR hdr;
   RawAddress bd_addr;
   char str[BTA_AG_AT_MAX_LEN + 1];
-  uint16_t num;
+  uint32_t num;
   uint8_t idx;   /* call number used by CLCC and CHLD */
   uint16_t lidx; /* long index, ex, HF indicator */
 } tBTA_AG_VAL;
index 967421d..9df2917 100644 (file)
@@ -247,6 +247,10 @@ static void send_indicator_update(const btif_hf_cb_t& control_block,
   BTA_AgResult(control_block.handle, BTA_AG_IND_RES, ag_res);
 }
 
+static bool is_nth_bit_enabled(uint32_t value, int n) {
+  return (value & (static_cast<uint32_t>(1) << n)) != 0;
+}
+
 void clear_phone_state_multihf(int idx) {
   btif_hf_cb[idx].call_setup_state = BTHF_CALL_STATE_IDLE;
   btif_hf_cb[idx].num_active = 0;
@@ -517,6 +521,16 @@ static void btif_hf_upstreams_evt(uint16_t event, char* p_param) {
                                         &btif_hf_cb[idx].connected_bda);
       }
       break;
+    case BTA_AG_AT_BIA_EVT:
+      if (p_data->val.hdr.status == BTA_AG_SUCCESS) {
+        uint32_t bia_mask_out = p_data->val.num;
+        bool service = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_SERVICE);
+        bool roam = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_ROAM);
+        bool signal = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_SIGNAL);
+        bool battery = !is_nth_bit_enabled(bia_mask_out, BTA_AG_IND_BATTCHG);
+        bt_hf_callbacks->AtBiaCallback(service, roam, signal, battery,
+                                       &btif_hf_cb[idx].connected_bda);
+      }
     default:
       BTIF_TRACE_WARNING("%s: Unhandled event: %d", __func__, event);
       break;
index cc57613..26d84fd 100644 (file)
@@ -210,6 +210,7 @@ const char* dump_hf_event(uint16_t event) {
     CASE_RETURN_STR(BTA_AG_AT_BCS_EVT)
     CASE_RETURN_STR(BTA_AG_AT_BIND_EVT)
     CASE_RETURN_STR(BTA_AG_AT_BIEV_EVT)
+    CASE_RETURN_STR(BTA_AG_AT_BIA_EVT)
 
     default:
       return "UNKNOWN MSG ID";
index dfab977..e115a15 100644 (file)
@@ -180,6 +180,20 @@ class Callbacks {
    */
   virtual void AtBievCallback(bthf_hf_ind_type_t ind_id, int ind_value,
                               RawAddress* bd_addr) = 0;
+
+  /**
+   * Callback for BIA. Pass the change in AG indicator activation.
+   * NOTE: Call, Call Setup and Call Held indicators are mandatory and cannot
+   *       be disabled. Thus, they are not included here.
+   *
+   * @param service whether HF should receive network service state update
+   * @param roam whether HF should receive roaming state update
+   * @param signal whether HF should receive signal strength update
+   * @param battery whether HF should receive AG battery level update
+   * @param bd_addr remote HF device address
+   */
+  virtual void AtBiaCallback(bool service, bool roam, bool signal, bool battery,
+                             RawAddress* bd_addr) = 0;
 };
 
 }  // namespace headset