Home | History | Annotate | Download | only in hf_client
      1 /******************************************************************************
      2  *
      3  *  Copyright (c) 2016 The Android Open Source Project
      4  *  Copyright (C) 2003-2012 Broadcom Corporation
      5  *
      6  *  Licensed under the Apache License, Version 2.0 (the "License");
      7  *  you may not use this file except in compliance with the License.
      8  *  You may obtain a copy of the License at:
      9  *
     10  *  http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  *  Unless required by applicable law or agreed to in writing, software
     13  *  distributed under the License is distributed on an "AS IS" BASIS,
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  *  See the License for the specific language governing permissions and
     16  *  limitations under the License.
     17  *
     18  ******************************************************************************/
     19 
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 
     24 #include "bt_utils.h"
     25 #include "bta_api.h"
     26 #include "bta_hf_client_api.h"
     27 #include "bta_hf_client_int.h"
     28 #include "bta_sys.h"
     29 #include "btcore/include/bdaddr.h"
     30 #include "osi/include/osi.h"
     31 #include "osi/include/properties.h"
     32 #include "utl.h"
     33 
     34 extern fixed_queue_t* btu_bta_alarm_queue;
     35 
     36 static const char* bta_hf_client_evt_str(uint16_t event);
     37 static const char* bta_hf_client_state_str(uint8_t state);
     38 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
     39 
     40 /* state machine states */
     41 enum {
     42   BTA_HF_CLIENT_INIT_ST,
     43   BTA_HF_CLIENT_OPENING_ST,
     44   BTA_HF_CLIENT_OPEN_ST,
     45   BTA_HF_CLIENT_CLOSING_ST
     46 };
     47 
     48 /* state machine action enumeration list */
     49 enum {
     50   BTA_HF_CLIENT_RFC_DO_CLOSE,
     51   BTA_HF_CLIENT_START_CLOSE,
     52   BTA_HF_CLIENT_START_OPEN,
     53   BTA_HF_CLIENT_RFC_ACP_OPEN,
     54   BTA_HF_CLIENT_SCO_LISTEN,
     55   BTA_HF_CLIENT_SCO_CONN_OPEN,
     56   BTA_HF_CLIENT_SCO_CONN_CLOSE,
     57   BTA_HF_CLIENT_SCO_OPEN,
     58   BTA_HF_CLIENT_SCO_CLOSE,
     59   BTA_HF_CLIENT_FREE_DB,
     60   BTA_HF_CLIENT_OPEN_FAIL,
     61   BTA_HF_CLIENT_RFC_OPEN,
     62   BTA_HF_CLIENT_RFC_FAIL,
     63   BTA_HF_CLIENT_DISC_INT_RES,
     64   BTA_HF_CLIENT_RFC_DO_OPEN,
     65   BTA_HF_CLIENT_DISC_FAIL,
     66   BTA_HF_CLIENT_RFC_CLOSE,
     67   BTA_HF_CLIENT_RFC_DATA,
     68   BTA_HF_CLIENT_DISC_ACP_RES,
     69   BTA_HF_CLIENT_SVC_CONN_OPEN,
     70   BTA_HF_CLIENT_SEND_AT_CMD,
     71   BTA_HF_CLIENT_NUM_ACTIONS,
     72 };
     73 
     74 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
     75 
     76 /* type for action functions */
     77 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
     78 
     79 /* action functions table, indexed with action enum */
     80 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
     81     /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
     82     /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
     83     /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
     84     /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
     85     /* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
     86     /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
     87     /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
     88     /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
     89     /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
     90     /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
     91     /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
     92     /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
     93     /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
     94     /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
     95     /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
     96     /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
     97     /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
     98     /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
     99     /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
    100     /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
    101     /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
    102 };
    103 
    104 /* state table information */
    105 #define BTA_HF_CLIENT_ACTIONS 2    /* number of actions */
    106 #define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
    107 #define BTA_HF_CLIENT_NUM_COLS 3   /* number of columns in state tables */
    108 
    109 /* state table for init state */
    110 const uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
    111     /* Event                    Action 1                       Action 2
    112        Next state */
    113     /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
    114                         BTA_HF_CLIENT_OPENING_ST},
    115     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    116                          BTA_HF_CLIENT_INIT_ST},
    117     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    118                               BTA_HF_CLIENT_INIT_ST},
    119     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    120                                BTA_HF_CLIENT_INIT_ST},
    121     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
    122                         BTA_HF_CLIENT_OPEN_ST},
    123     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    124                          BTA_HF_CLIENT_INIT_ST},
    125     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    126                              BTA_HF_CLIENT_INIT_ST},
    127     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    128                         BTA_HF_CLIENT_INIT_ST},
    129     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
    130                             BTA_HF_CLIENT_INIT_ST},
    131     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    132                             BTA_HF_CLIENT_INIT_ST},
    133     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    134                        BTA_HF_CLIENT_INIT_ST},
    135     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    136                          BTA_HF_CLIENT_INIT_ST},
    137     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    138                         BTA_HF_CLIENT_INIT_ST},
    139     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    140                          BTA_HF_CLIENT_INIT_ST},
    141     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    142                            BTA_HF_CLIENT_INIT_ST},
    143 };
    144 
    145 /* state table for opening state */
    146 const uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
    147     /* Event                    Action 1                       Action 2
    148        Next state */
    149     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
    150                         BTA_HF_CLIENT_OPENING_ST},
    151     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
    152                          BTA_HF_CLIENT_CLOSING_ST},
    153     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    154                               BTA_HF_CLIENT_OPENING_ST},
    155     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    156                                BTA_HF_CLIENT_OPENING_ST},
    157     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE,
    158                         BTA_HF_CLIENT_OPEN_ST},
    159     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
    160                          BTA_HF_CLIENT_INIT_ST},
    161     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    162                              BTA_HF_CLIENT_OPENING_ST},
    163     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    164                         BTA_HF_CLIENT_OPENING_ST},
    165     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    166                             BTA_HF_CLIENT_OPENING_ST},
    167     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
    168                             BTA_HF_CLIENT_OPENING_ST},
    169     /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
    170                        BTA_HF_CLIENT_OPENING_ST},
    171     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
    172                          BTA_HF_CLIENT_INIT_ST},
    173     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    174                         BTA_HF_CLIENT_OPENING_ST},
    175     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    176                          BTA_HF_CLIENT_OPENING_ST},
    177     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    178                            BTA_HF_CLIENT_OPENING_ST},
    179 };
    180 
    181 /* state table for open state */
    182 const uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
    183     /* Event                    Action 1                       Action 2
    184        Next state */
    185     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
    186                         BTA_HF_CLIENT_OPEN_ST},
    187     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
    188                          BTA_HF_CLIENT_CLOSING_ST},
    189     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
    190                               BTA_HF_CLIENT_OPEN_ST},
    191     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
    192                                BTA_HF_CLIENT_OPEN_ST},
    193     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    194                         BTA_HF_CLIENT_OPEN_ST},
    195     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
    196                          BTA_HF_CLIENT_INIT_ST},
    197     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    198                              BTA_HF_CLIENT_OPEN_ST},
    199     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
    200                         BTA_HF_CLIENT_OPEN_ST},
    201     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
    202                             BTA_HF_CLIENT_OPEN_ST},
    203     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    204                             BTA_HF_CLIENT_OPEN_ST},
    205     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    206                        BTA_HF_CLIENT_OPEN_ST},
    207     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    208                          BTA_HF_CLIENT_OPEN_ST},
    209     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
    210                         BTA_HF_CLIENT_OPEN_ST},
    211     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
    212                          BTA_HF_CLIENT_OPEN_ST},
    213     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
    214                            BTA_HF_CLIENT_OPEN_ST},
    215 };
    216 
    217 /* state table for closing state */
    218 const uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
    219     /* Event                    Action 1                       Action 2
    220        Next state */
    221     /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
    222                         BTA_HF_CLIENT_CLOSING_ST},
    223     /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    224                          BTA_HF_CLIENT_CLOSING_ST},
    225     /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    226                               BTA_HF_CLIENT_CLOSING_ST},
    227     /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    228                                BTA_HF_CLIENT_CLOSING_ST},
    229     /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    230                         BTA_HF_CLIENT_CLOSING_ST},
    231     /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
    232                          BTA_HF_CLIENT_INIT_ST},
    233     /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    234                              BTA_HF_CLIENT_CLOSING_ST},
    235     /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    236                         BTA_HF_CLIENT_CLOSING_ST},
    237     /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
    238                             BTA_HF_CLIENT_CLOSING_ST},
    239     /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
    240                             BTA_HF_CLIENT_INIT_ST},
    241     /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    242                        BTA_HF_CLIENT_CLOSING_ST},
    243     /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    244                          BTA_HF_CLIENT_CLOSING_ST},
    245     /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    246                         BTA_HF_CLIENT_CLOSING_ST},
    247     /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    248                          BTA_HF_CLIENT_CLOSING_ST},
    249     /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
    250                            BTA_HF_CLIENT_CLOSING_ST},
    251 };
    252 
    253 /* type for state table */
    254 typedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
    255 
    256 /* state table */
    257 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
    258     bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
    259     bta_hf_client_st_closing};
    260 
    261 /* HF Client control block */
    262 tBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
    263 
    264 /* Event handler for the state machine */
    265 static const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
    266                                                BTA_HfClientDisable};
    267 
    268 /*******************************************************************************
    269  *
    270  * Function         bta_hf_client_cb_arr_init
    271  *
    272  * Description      Initialize entire control block array set
    273  *
    274  *
    275  * Returns          void
    276  *
    277  ******************************************************************************/
    278 void bta_hf_client_cb_arr_init() {
    279   memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
    280 
    281   // reset the handles and make the CBs non-allocated
    282   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    283     // Allocate the handles in increasing order of indices
    284     bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
    285     bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
    286   }
    287 }
    288 
    289 /*******************************************************************************
    290  *
    291  * Function         bta_hf_client_cb_init
    292  *
    293  * Description      Initialize an HF_Client service control block. Assign the
    294  *                  handle to cb->handle.
    295  *
    296  *
    297  *
    298  * Returns          void
    299  *
    300  ******************************************************************************/
    301 void bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
    302   APPL_TRACE_DEBUG("%s", __func__);
    303 
    304   // Free any memory we need to explicity release
    305   alarm_free(client_cb->collision_timer);
    306 
    307   // Memset the rest of the block
    308   memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
    309 
    310   // Re allocate any variables required
    311   client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
    312   client_cb->handle = handle;
    313   client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
    314 }
    315 
    316 /*******************************************************************************
    317  *
    318  * Function         bta_hf_client_resume_open
    319  *
    320  * Description      Resume opening process.
    321  *
    322  *
    323  * Returns          void
    324  *
    325  ******************************************************************************/
    326 void bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
    327   APPL_TRACE_DEBUG("%s", __func__);
    328 
    329   /* resume opening process.  */
    330   if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
    331     client_cb->state = BTA_HF_CLIENT_OPENING_ST;
    332     tBTA_HF_CLIENT_DATA msg;
    333     msg.hdr.layer_specific = client_cb->handle;
    334     bta_hf_client_start_open(&msg);
    335   }
    336 }
    337 
    338 /*******************************************************************************
    339  *
    340  * Function         bta_hf_client_collision_timer_cback
    341  *
    342  * Description      HF Client connection collision timer callback
    343  *
    344  *
    345  * Returns          void
    346  *
    347  ******************************************************************************/
    348 static void bta_hf_client_collision_timer_cback(void* data) {
    349   APPL_TRACE_DEBUG("%s", __func__);
    350   tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
    351 
    352   /* If the peer haven't opened connection, restart opening process */
    353   bta_hf_client_resume_open(client_cb);
    354 }
    355 
    356 /*******************************************************************************
    357  *
    358  * Function         bta_hf_client_collision_cback
    359  *
    360  * Description      Get notified about collision.
    361  *
    362  *
    363  * Returns          void
    364  *
    365  ******************************************************************************/
    366 void bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
    367                                    uint8_t id, UNUSED_ATTR uint8_t app_id,
    368                                    BD_ADDR peer_addr) {
    369   tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
    370   if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
    371     if (id == BTA_ID_SYS) /* ACL collision */
    372     {
    373       APPL_TRACE_WARNING("HF Client found collision (ACL) ...");
    374     } else if (id == BTA_ID_HS) /* RFCOMM collision */
    375     {
    376       APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ...");
    377     } else {
    378       APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ...");
    379     }
    380 
    381     client_cb->state = BTA_HF_CLIENT_INIT_ST;
    382 
    383     /* Cancel SDP if it had been started. */
    384     if (client_cb->p_disc_db) {
    385       (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
    386       bta_hf_client_free_db(NULL);
    387     }
    388 
    389     /* reopen registered server */
    390     /* Collision may be detected before or after we close servers. */
    391     // bta_hf_client_start_server();
    392 
    393     /* Start timer to handle connection opening restart */
    394     alarm_set_on_queue(client_cb->collision_timer,
    395                        BTA_HF_CLIENT_COLLISION_TIMER_MS,
    396                        bta_hf_client_collision_timer_cback, (void*)client_cb,
    397                        btu_bta_alarm_queue);
    398   }
    399 }
    400 
    401 /*******************************************************************************
    402  *
    403  * Function         bta_hf_client_api_enable
    404  *
    405  * Description      Handle an API enable event.
    406  *
    407  *
    408  * Returns          void
    409  *
    410  ******************************************************************************/
    411 tBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
    412                                      tBTA_SEC sec_mask,
    413                                      tBTA_HF_CLIENT_FEAT features,
    414                                      const char* p_service_name) {
    415   /* If already registered then return error */
    416   if (bta_sys_is_register(BTA_ID_HS)) {
    417     APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
    418     return BTA_FAILURE;
    419   }
    420 
    421   /* register with BTA system manager */
    422   bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
    423 
    424   /* reset the control blocks */
    425   bta_hf_client_cb_arr_init();
    426 
    427   bta_hf_client_cb_arr.p_cback = p_cback;
    428   bta_hf_client_cb_arr.serv_sec_mask = sec_mask;
    429   bta_hf_client_cb_arr.features = features;
    430 
    431   /* create SDP records */
    432   bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
    433 
    434   /* set same setting as AG does */
    435   BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
    436 
    437   bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
    438 
    439   /* Set the Audio service class bit */
    440   tBTA_UTL_COD cod;
    441   cod.service = BTM_COD_SERVICE_AUDIO;
    442   utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
    443 
    444   /* start RFCOMM server */
    445   bta_hf_client_start_server();
    446 
    447   return BTA_SUCCESS;
    448 }
    449 
    450 /*******************************************************************************
    451  *
    452  * Function         bta_hf_client_find_cb_by_handle
    453  *
    454  * Description      Finds the control block by handle provided
    455  *
    456  *                  handle: Handle as obtained from BTA_HfClientOpen call
    457  *
    458  *
    459  * Returns          Control block corresponding to the handle and NULL if
    460  *                  none exists
    461  *
    462  ******************************************************************************/
    463 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
    464   // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
    465   if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
    466     APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1,
    467                      HF_CLIENT_MAX_DEVICES, handle);
    468     return NULL;
    469   }
    470 
    471   // Check if the associated index is allocated. Index is (handle - 1).
    472   if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
    473     return &(bta_hf_client_cb_arr.cb[handle - 1]);
    474 
    475   APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
    476   return NULL;
    477 }
    478 
    479 /*******************************************************************************
    480  *
    481  * Function         bta_hf_client_find_cb_by_bda
    482  *
    483  * Description      Finds the control block by handle provided
    484  *
    485  *                  bda: BD_ADDR of the device to find the handle for.
    486  *                  Since there can only be one HF connection for a device
    487  *                  we should always find a unique block
    488  *
    489  * Returns          Control block corresponding to the BD_ADDR and NULL if
    490  *                  none exists
    491  *
    492  ******************************************************************************/
    493 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR peer_addr) {
    494   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    495     // Check if the associated index is allocated and that BD ADDR matches
    496     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
    497     if (client_cb->is_allocated && !bdcmp(peer_addr, client_cb->peer_addr)) {
    498       return client_cb;
    499     } else {
    500       APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
    501                          i, client_cb->is_allocated);
    502     }
    503   }
    504   APPL_TRACE_ERROR("%s: block not found", __func__);
    505   return NULL;
    506 }
    507 
    508 /*******************************************************************************
    509  *
    510  * Function         bta_hf_client_find_cb_by_rfc_handle
    511  *
    512  * Description      Finds the control block by RFC handle provided.
    513  *
    514  *                  handle: RFC handle for the established connection
    515  *
    516  *
    517  * Returns          Control block corresponding to the handle and NULL if none
    518  *                  exists
    519  *
    520  ******************************************************************************/
    521 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
    522   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    523     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
    524     bool is_allocated = client_cb->is_allocated;
    525     uint16_t conn_handle = client_cb->conn_handle;
    526 
    527     APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__,
    528                      handle, is_allocated, conn_handle);
    529 
    530     if (is_allocated && conn_handle == handle) {
    531       return client_cb;
    532     }
    533 
    534     APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__,
    535                        handle, is_allocated, conn_handle);
    536   }
    537 
    538   APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle);
    539   return NULL;
    540 }
    541 
    542 /*******************************************************************************
    543  *
    544  * Function         bta_hf_client_find_cb_by_sco_handle
    545  *
    546  * Description      Finds the control block by sco handle provided
    547  *
    548  *                  handle: sco handle
    549  *
    550  *
    551  * Returns          Control block corresponding to the sco handle and
    552  *                  none if none exists
    553  *
    554  ******************************************************************************/
    555 tBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
    556   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    557     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
    558     if (client_cb->is_allocated && client_cb->sco_idx == handle) {
    559       return client_cb;
    560     }
    561   }
    562   APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
    563   return NULL;
    564 }
    565 
    566 /*******************************************************************************
    567  *
    568  * Function         bta_hf_client_allocate_handle
    569  *
    570  * Description      Allocates a handle for the new BD ADDR that needs a new RF
    571  *                  channel for HF connection. If the channel cannot be created
    572  *                  for a reason then false is returned
    573  *
    574  *                  bd_addr: Address of the device for which this block is
    575  *                  being created. Single device can only have one block.
    576  *                  p_handle: OUT variable to store the outcome of allocate. If
    577  *                  allocate failed then value is not valid
    578  *
    579  *
    580  * Returns          true if the creation of p_handle succeeded, false otherwise
    581  *
    582  ******************************************************************************/
    583 bool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) {
    584   tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
    585   if (existing_cb != NULL) {
    586     BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
    587                      __func__);
    588     return false;
    589   }
    590   /* Check that we do not have a request to for same device in the control
    591    * blocks */
    592   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    593     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
    594     if (client_cb->is_allocated) {
    595       APPL_TRACE_WARNING("%s: control block already used index %d", __func__,
    596                          i);
    597       continue;
    598     }
    599 
    600     // Reset the client control block
    601     bta_hf_client_cb_init(client_cb, client_cb->handle);
    602 
    603     *p_handle = client_cb->handle;
    604     APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__,
    605                      client_cb->handle);
    606 
    607     client_cb->is_allocated = true;
    608     bdcpy(client_cb->peer_addr, bd_addr);
    609     bta_hf_client_at_init(client_cb);
    610     return true;
    611   }
    612 
    613   return false;
    614   APPL_TRACE_ERROR("%s: all control blocks in use!", __func__);
    615 }
    616 
    617 /*******************************************************************************
    618  *
    619  * Function         bta_hf_client_app_callback
    620  *
    621  * Description      Calls the application callback
    622  *
    623  *
    624  * Returns          Void
    625  *
    626  ******************************************************************************/
    627 void bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
    628   if (bta_hf_client_cb_arr.p_cback != NULL) {
    629     bta_hf_client_cb_arr.p_cback(event, data);
    630   }
    631 }
    632 
    633 /*******************************************************************************
    634  *
    635  * Function         bta_hf_client_api_disable
    636  *
    637  * Description      Handle an API disable event.
    638  *
    639  *
    640  * Returns          void
    641  *
    642  ******************************************************************************/
    643 void bta_hf_client_api_disable() {
    644   if (!bta_sys_is_register(BTA_ID_HS)) {
    645     APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ...");
    646     return;
    647   }
    648 
    649   /* Remove the collision handler */
    650   bta_sys_collision_register(BTA_ID_HS, NULL);
    651 
    652   bta_hf_client_cb_arr.deregister = true;
    653 
    654   /* remove sdp record */
    655   bta_hf_client_del_record(&bta_hf_client_cb_arr);
    656 
    657   /* remove rfcomm server */
    658   bta_hf_client_close_server();
    659 
    660   /* reinit the control block */
    661   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    662     if (bta_hf_client_cb_arr.cb[i].is_allocated) {
    663       bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
    664     }
    665   }
    666 
    667   /* De-register with BTA system manager */
    668   bta_sys_deregister(BTA_ID_HS);
    669 }
    670 
    671 /*******************************************************************************
    672  *
    673  * Function         bta_hf_client_hdl_event
    674  *
    675  * Description      Data HF Client main event handling function.
    676  *
    677  *
    678  * Returns          bool
    679  *
    680  ******************************************************************************/
    681 bool bta_hf_client_hdl_event(BT_HDR* p_msg) {
    682   APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
    683                    bta_hf_client_evt_str(p_msg->event), p_msg->event);
    684   bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
    685   return true;
    686 }
    687 
    688 /*******************************************************************************
    689  *
    690  * Function         bta_hf_client_sm_execute
    691  *
    692  * Description      State machine event handling function for HF Client
    693  *
    694  *
    695  * Returns          void
    696  *
    697  ******************************************************************************/
    698 void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
    699   tBTA_HF_CLIENT_CB* client_cb =
    700       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
    701   if (client_cb == NULL) {
    702     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
    703                      p_data->hdr.layer_specific);
    704     return;
    705   }
    706 
    707   tBTA_HF_CLIENT_ST_TBL state_table;
    708   uint8_t action;
    709   int i;
    710 
    711   uint16_t in_event = event;
    712   uint8_t in_state = client_cb->state;
    713 
    714   /* Ignore displaying of AT results when not connected (Ignored in state
    715    * machine) */
    716   if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
    717     APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
    718                      client_cb->state,
    719                      bta_hf_client_state_str(client_cb->state), event,
    720                      bta_hf_client_evt_str(event));
    721   }
    722 
    723   event &= 0x00FF;
    724   if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
    725     APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
    726     return;
    727   }
    728 
    729   /* look up the state table for the current state */
    730   state_table = bta_hf_client_st_tbl[client_cb->state];
    731 
    732   /* set next state */
    733   client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
    734 
    735   /* execute action functions */
    736   for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
    737     action = state_table[event][i];
    738     if (action != BTA_HF_CLIENT_IGNORE) {
    739       (*bta_hf_client_action[action])(p_data);
    740     } else {
    741       break;
    742     }
    743   }
    744 
    745   /* If the state has changed then notify the app of the corresponding change */
    746   if (in_state != client_cb->state) {
    747     APPL_TRACE_DEBUG(
    748         "%s: notifying state change to %d -> %d "
    749         "device %02x:%02x:%02x:%02x:%02x:%02x",
    750         __func__, in_state, client_cb->state, client_cb->peer_addr[0],
    751         client_cb->peer_addr[1], client_cb->peer_addr[2],
    752         client_cb->peer_addr[3], client_cb->peer_addr[4],
    753         client_cb->peer_addr[5]);
    754     tBTA_HF_CLIENT evt;
    755     memset(&evt, 0, sizeof(evt));
    756     bdcpy(evt.bd_addr, client_cb->peer_addr);
    757     if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
    758       bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
    759     } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
    760       evt.open.handle = client_cb->handle;
    761       bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
    762     }
    763   }
    764 
    765   /* if the next state is INIT then release the cb for future use */
    766   if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
    767     APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__,
    768                      client_cb->handle);
    769     client_cb->is_allocated = false;
    770   }
    771 
    772   APPL_TRACE_EVENT(
    773       "%s: device %02x:%02x:%02x:%02x:%02x:%02x "
    774       "state change: [%s] -> [%s] after Event [%s]",
    775       __func__, client_cb->peer_addr[0], client_cb->peer_addr[1],
    776       client_cb->peer_addr[2], client_cb->peer_addr[3], client_cb->peer_addr[4],
    777       client_cb->peer_addr[5], bta_hf_client_state_str(in_state),
    778       bta_hf_client_state_str(client_cb->state),
    779       bta_hf_client_evt_str(in_event));
    780 }
    781 
    782 static void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
    783   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
    784 
    785   bta_hf_client_send_at_bia(client_cb);
    786   bta_hf_client_send_at_ccwa(client_cb, true);
    787   bta_hf_client_send_at_cmee(client_cb, true);
    788   bta_hf_client_send_at_cops(client_cb, false);
    789   bta_hf_client_send_at_btrh(client_cb, true, 0);
    790   bta_hf_client_send_at_clip(client_cb, true);
    791 }
    792 
    793 /*******************************************************************************
    794  *
    795  * Function         bta_hf_client_slc_seq
    796  *
    797  * Description      Handles AT commands sequence required for SLC creation
    798  *
    799  *
    800  * Returns          void
    801  *
    802  ******************************************************************************/
    803 void bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
    804   APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u",
    805                    client_cb->at_cb.current_cmd);
    806 
    807   if (error) {
    808     /* SLC establishment error, sent close rfcomm event */
    809     APPL_TRACE_ERROR(
    810         "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
    811         client_cb->at_cb.current_cmd);
    812 
    813     tBTA_HF_CLIENT_DATA msg;
    814     msg.hdr.layer_specific = client_cb->handle;
    815     bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
    816     return;
    817   }
    818 
    819   if (client_cb->svc_conn) {
    820     APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__,
    821                        client_cb->handle);
    822     return;
    823   }
    824 
    825   switch (client_cb->at_cb.current_cmd) {
    826     case BTA_HF_CLIENT_AT_NONE:
    827       bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
    828       break;
    829 
    830     case BTA_HF_CLIENT_AT_BRSF:
    831       if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
    832           (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
    833         bta_hf_client_send_at_bac(client_cb);
    834         break;
    835       }
    836 
    837       bta_hf_client_send_at_cind(client_cb, false);
    838       break;
    839 
    840     case BTA_HF_CLIENT_AT_BAC:
    841       bta_hf_client_send_at_cind(client_cb, false);
    842       break;
    843 
    844     case BTA_HF_CLIENT_AT_CIND:
    845       bta_hf_client_send_at_cind(client_cb, true);
    846       break;
    847 
    848     case BTA_HF_CLIENT_AT_CIND_STATUS:
    849       bta_hf_client_send_at_cmer(client_cb, true);
    850       break;
    851 
    852     case BTA_HF_CLIENT_AT_CMER:
    853       if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
    854           bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
    855         bta_hf_client_send_at_chld(client_cb, '?', 0);
    856       } else {
    857         tBTA_HF_CLIENT_DATA msg;
    858         msg.hdr.layer_specific = client_cb->handle;
    859         bta_hf_client_svc_conn_open(&msg);
    860         send_post_slc_cmd(client_cb);
    861       }
    862       break;
    863 
    864     case BTA_HF_CLIENT_AT_CHLD: {
    865       tBTA_HF_CLIENT_DATA msg;
    866       msg.hdr.layer_specific = client_cb->handle;
    867       bta_hf_client_svc_conn_open(&msg);
    868       send_post_slc_cmd(client_cb);
    869       break;
    870     }
    871 
    872     default: {
    873       /* If happen there is a bug in SLC creation procedure... */
    874       APPL_TRACE_ERROR(
    875           "HFPClient: Failed to create SLCdue to unexpected AT command, "
    876           "disconnecting (%u)",
    877           client_cb->at_cb.current_cmd);
    878 
    879       tBTA_HF_CLIENT_DATA msg;
    880       msg.hdr.layer_specific = client_cb->handle;
    881       bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
    882       break;
    883     }
    884   }
    885 }
    886 
    887 #ifndef CASE_RETURN_STR
    888 #define CASE_RETURN_STR(const) \
    889   case const:                  \
    890     return #const;
    891 #endif
    892 
    893 static const char* bta_hf_client_evt_str(uint16_t event) {
    894   switch (event) {
    895     CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
    896     CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
    897     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
    898     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
    899     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
    900     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
    901     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
    902     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
    903     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
    904     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
    905     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
    906     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
    907     CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
    908     CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
    909     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
    910     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
    911     CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
    912     default:
    913       return "Unknown HF Client Event";
    914   }
    915 }
    916 
    917 static const char* bta_hf_client_state_str(uint8_t state) {
    918   switch (state) {
    919     CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
    920     CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
    921     CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
    922     CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
    923     default:
    924       return "Unknown HF Client State";
    925   }
    926 }
    927 
    928 void bta_hf_client_dump_statistics(int fd) {
    929   dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
    930 
    931   // We dump statistics for all control blocks
    932   for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
    933     tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
    934     if (!client_cb->is_allocated) {
    935       // Skip the blocks which are not allocated
    936       continue;
    937     }
    938 
    939     dprintf(fd, "  Control block #%d\n", i + 1);
    940 
    941     // Device name
    942     dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n",
    943             client_cb->peer_addr[0], client_cb->peer_addr[1],
    944             client_cb->peer_addr[2], client_cb->peer_addr[3],
    945             client_cb->peer_addr[4], client_cb->peer_addr[5]);
    946 
    947     // State machine state
    948     dprintf(fd, "    State Machine State: %s\n",
    949             bta_hf_client_state_str(client_cb->state));
    950 
    951     // Local RFC channelfor communication
    952     dprintf(fd, "    RFCOMM Channel (local) %d\n", client_cb->conn_handle);
    953 
    954     // BTA Handle shared between BTA and client (ex BTIF)
    955     dprintf(fd, "    BTA Generated handle %d\n", client_cb->handle);
    956   }
    957 }
    958