Home | History | Annotate | Download | only in hf_client
      1 /******************************************************************************
      2  *
      3  *  Copyright (c) 2014 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 <string.h>
     21 #include <stdlib.h>
     22 
     23 #include "osi/include/osi.h"
     24 #include "osi/include/properties.h"
     25 #include "bt_utils.h"
     26 #include "bta_api.h"
     27 #include "bta_sys.h"
     28 #include "bta_hf_client_api.h"
     29 #include "bta_hf_client_int.h"
     30 
     31 /* uncomment to enable extra debug */
     32 /* #define BTA_HF_CLIENT_DEBUG TRUE */
     33 
     34 #ifndef BTA_HF_CLIENT_DEBUG
     35 #define BTA_HF_CLIENT_DEBUG FALSE
     36 #endif
     37 
     38 extern fixed_queue_t *btu_bta_alarm_queue;
     39 
     40 #if BTA_HF_CLIENT_DEBUG == TRUE
     41 static char *bta_hf_client_evt_str(UINT16 event);
     42 static char *bta_hf_client_state_str(UINT8 state);
     43 #endif
     44 
     45 /* state machine states */
     46 enum
     47 {
     48     BTA_HF_CLIENT_INIT_ST,
     49     BTA_HF_CLIENT_OPENING_ST,
     50     BTA_HF_CLIENT_OPEN_ST,
     51     BTA_HF_CLIENT_CLOSING_ST
     52 };
     53 
     54 /* state machine action enumeration list */
     55 enum
     56 {
     57     BTA_HF_CLIENT_REGISTER,
     58     BTA_HF_CLIENT_DEREGISTER,
     59     BTA_HF_CLIENT_START_DEREG,
     60     BTA_HF_CLIENT_RFC_DO_CLOSE,
     61     BTA_HF_CLIENT_START_CLOSE,
     62     BTA_HF_CLIENT_START_OPEN,
     63     BTA_HF_CLIENT_RFC_ACP_OPEN,
     64     BTA_HF_CLIENT_SCO_LISTEN,
     65     BTA_HF_CLIENT_SCO_CONN_OPEN,
     66     BTA_HF_CLIENT_SCO_CONN_CLOSE,
     67     BTA_HF_CLIENT_SCO_OPEN,
     68     BTA_HF_CLIENT_SCO_CLOSE,
     69     BTA_HF_CLIENT_SCO_SHUTDOWN,
     70     BTA_HF_CLIENT_FREE_DB,
     71     BTA_HF_CLIENT_OPEN_FAIL,
     72     BTA_HF_CLIENT_RFC_OPEN,
     73     BTA_HF_CLIENT_RFC_FAIL,
     74     BTA_HF_CLIENT_DISC_INT_RES,
     75     BTA_HF_CLIENT_RFC_DO_OPEN,
     76     BTA_HF_CLIENT_DISC_FAIL,
     77     BTA_HF_CLIENT_RFC_CLOSE,
     78     BTA_HF_CLIENT_RFC_DATA,
     79     BTA_HF_CLIENT_DISC_ACP_RES,
     80     BTA_HF_CLIENT_SVC_CONN_OPEN,
     81     BTA_HF_CLIENT_SEND_AT_CMD,
     82     BTA_HF_CLIENT_NUM_ACTIONS,
     83 };
     84 
     85 #define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
     86 
     87 /* type for action functions */
     88 typedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA *p_data);
     89 
     90 /* action functions table, indexed with action enum */
     91 const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] =
     92 {
     93 /* BTA_HF_CLIENT_REGISTER */      bta_hf_client_register,
     94 /* BTA_HF_CLIENT_DEREGISTER */    bta_hf_client_deregister,
     95 /* BTA_HF_CLIENT_START_DEREG */   bta_hf_client_start_dereg,
     96 /* BTA_HF_CLIENT_RFC_DO_CLOSE */  bta_hf_client_rfc_do_close,
     97 /* BTA_HF_CLIENT_START_CLOSE */   bta_hf_client_start_close,
     98 /* BTA_HF_CLIENT_START_OPEN */    bta_hf_client_start_open,
     99 /* BTA_HF_CLIENT_RFC_ACP_OPEN */  bta_hf_client_rfc_acp_open,
    100 /* BTA_HF_CLIENT_SCO_LISTEN */    bta_hf_client_sco_listen,
    101 /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
    102 /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
    103 /* BTA_HF_CLIENT_SCO_OPEN */      bta_hf_client_sco_open,
    104 /* BTA_HF_CLIENT_SCO_CLOSE */     bta_hf_client_sco_close,
    105 /* BTA_HF_CLIENT_SCO_SHUTDOWN */  bta_hf_client_sco_shutdown,
    106 /* BTA_HF_CLIENT_FREE_DB */       bta_hf_client_free_db,
    107 /* BTA_HF_CLIENT_OPEN_FAIL */     bta_hf_client_open_fail,
    108 /* BTA_HF_CLIENT_RFC_OPEN */      bta_hf_client_rfc_open,
    109 /* BTA_HF_CLIENT_RFC_FAIL */      bta_hf_client_rfc_fail,
    110 /* BTA_HF_CLIENT_DISC_INT_RES */  bta_hf_client_disc_int_res,
    111 /* BTA_HF_CLIENT_RFC_DO_OPEN */   bta_hf_client_rfc_do_open,
    112 /* BTA_HF_CLIENT_DISC_FAIL */     bta_hf_client_disc_fail,
    113 /* BTA_HF_CLIENT_RFC_CLOSE */     bta_hf_client_rfc_close,
    114 /* BTA_HF_CLIENT_RFC_DATA */      bta_hf_client_rfc_data,
    115 /* BTA_HF_CLIENT_DISC_ACP_RES */  bta_hf_client_disc_acp_res,
    116 /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
    117 /* BTA_HF_CLIENT_SEND_AT_CMD */   bta_hf_client_send_at_cmd,
    118 };
    119 
    120 /* state table information */
    121 #define BTA_HF_CLIENT_ACTIONS              2       /* number of actions */
    122 #define BTA_HF_CLIENT_NEXT_STATE           2       /* position of next state */
    123 #define BTA_HF_CLIENT_NUM_COLS             3       /* number of columns in state tables */
    124 
    125 /* state table for init state */
    126 const UINT8 bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] =
    127 {
    128 /* Event                    Action 1                       Action 2                       Next state */
    129 /* API_REGISTER_EVT */      {BTA_HF_CLIENT_REGISTER,       BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    130 /* API_DEREGISTER_EVT */    {BTA_HF_CLIENT_DEREGISTER,     BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    131 /* API_OPEN_EVT */          {BTA_HF_CLIENT_START_OPEN,     BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    132 /* API_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    133 /* API_AUDIO_OPEN_EVT */    {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    134 /* API_AUDIO_CLOSE_EVT */   {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    135 /* RFC_OPEN_EVT */          {BTA_HF_CLIENT_RFC_ACP_OPEN,   BTA_HF_CLIENT_SCO_LISTEN,      BTA_HF_CLIENT_OPEN_ST},
    136 /* RFC_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    137 /* RFC_SRV_CLOSE_EVT */     {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    138 /* RFC_DATA_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    139 /* DISC_ACP_RES_EVT */      {BTA_HF_CLIENT_FREE_DB,        BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    140 /* DISC_INT_RES_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    141 /* DISC_OK_EVT */           {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    142 /* DISC_FAIL_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    143 /* SCO_OPEN_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    144 /* SCO_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    145 /* SEND_AT_CMD_EVT */       {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    146 };
    147 
    148 /* state table for opening state */
    149 const UINT8 bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] =
    150 {
    151 /* Event                    Action 1                       Action 2                       Next state */
    152 /* API_REGISTER_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    153 /* API_DEREGISTER_EVT */    {BTA_HF_CLIENT_RFC_DO_CLOSE,   BTA_HF_CLIENT_START_DEREG,     BTA_HF_CLIENT_CLOSING_ST},
    154 /* API_OPEN_EVT */          {BTA_HF_CLIENT_OPEN_FAIL,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    155 /* API_CLOSE_EVT */         {BTA_HF_CLIENT_RFC_DO_CLOSE,   BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    156 /* API_AUDIO_OPEN_EVT */    {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    157 /* API_AUDIO_CLOSE_EVT */   {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    158 /* RFC_OPEN_EVT */          {BTA_HF_CLIENT_RFC_OPEN,       BTA_HF_CLIENT_SCO_LISTEN,      BTA_HF_CLIENT_OPEN_ST},
    159 /* RFC_CLOSE_EVT */         {BTA_HF_CLIENT_RFC_FAIL,       BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    160 /* RFC_SRV_CLOSE_EVT */     {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    161 /* RFC_DATA_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    162 /* DISC_ACP_RES_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    163 /* DISC_INT_RES_EVT */      {BTA_HF_CLIENT_DISC_INT_RES,   BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    164 /* DISC_OK_EVT */           {BTA_HF_CLIENT_RFC_DO_OPEN,    BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    165 /* DISC_FAIL_EVT */         {BTA_HF_CLIENT_DISC_FAIL,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    166 /* SCO_OPEN_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    167 /* SCO_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    168 /* SEND_AT_CMD_EVT */       {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPENING_ST},
    169 };
    170 
    171 /* state table for open state */
    172 const UINT8 bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] =
    173 {
    174 /* Event                    Action 1                       Action 2                       Next state */
    175 /* API_REGISTER_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    176 /* API_DEREGISTER_EVT */    {BTA_HF_CLIENT_START_CLOSE,    BTA_HF_CLIENT_START_DEREG,     BTA_HF_CLIENT_CLOSING_ST},
    177 /* API_OPEN_EVT */          {BTA_HF_CLIENT_OPEN_FAIL,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    178 /* API_CLOSE_EVT */         {BTA_HF_CLIENT_START_CLOSE,    BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    179 /* API_AUDIO_OPEN_EVT */    {BTA_HF_CLIENT_SCO_OPEN,       BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    180 /* API_AUDIO_CLOSE_EVT */   {BTA_HF_CLIENT_SCO_CLOSE,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    181 /* RFC_OPEN_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    182 /* RFC_CLOSE_EVT */         {BTA_HF_CLIENT_RFC_CLOSE,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    183 /* RFC_SRV_CLOSE_EVT */     {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    184 /* RFC_DATA_EVT */          {BTA_HF_CLIENT_RFC_DATA,       BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    185 /* DISC_ACP_RES_EVT */      {BTA_HF_CLIENT_DISC_ACP_RES,   BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    186 /* DISC_INT_RES_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    187 /* DISC_OK_EVT */           {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    188 /* DISC_FAIL_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    189 /* SCO_OPEN_EVT */          {BTA_HF_CLIENT_SCO_CONN_OPEN,  BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    190 /* SCO_CLOSE_EVT */         {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    191 /* SEND_AT_CMD_EVT */       {BTA_HF_CLIENT_SEND_AT_CMD,    BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_OPEN_ST},
    192 };
    193 
    194 /* state table for closing state */
    195 const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] =
    196 {
    197 /* Event                    Action 1                       Action 2                       Next state */
    198 /* API_REGISTER_EVT */      {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    199 /* API_DEREGISTER_EVT */    {BTA_HF_CLIENT_START_DEREG,    BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    200 /* API_OPEN_EVT */          {BTA_HF_CLIENT_OPEN_FAIL,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    201 /* API_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    202 /* API_AUDIO_OPEN_EVT */    {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    203 /* API_AUDIO_CLOSE_EVT */   {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    204 /* RFC_OPEN_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    205 /* RFC_CLOSE_EVT */         {BTA_HF_CLIENT_RFC_CLOSE,      BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    206 /* RFC_SRV_CLOSE_EVT */     {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    207 /* RFC_DATA_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    208 /* DISC_ACP_RES_EVT */      {BTA_HF_CLIENT_FREE_DB,        BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    209 /* DISC_INT_RES_EVT */      {BTA_HF_CLIENT_FREE_DB,        BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_INIT_ST},
    210 /* DISC_OK_EVT */           {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    211 /* DISC_FAIL_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    212 /* SCO_OPEN_EVT */          {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    213 /* SCO_CLOSE_EVT */         {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    214 /* SEND_AT_CMD_EVT */       {BTA_HF_CLIENT_IGNORE,         BTA_HF_CLIENT_IGNORE,          BTA_HF_CLIENT_CLOSING_ST},
    215 };
    216 
    217 /* type for state table */
    218 typedef const UINT8 (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
    219 
    220 /* state table */
    221 const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] =
    222 {
    223     bta_hf_client_st_init,
    224     bta_hf_client_st_opening,
    225     bta_hf_client_st_open,
    226     bta_hf_client_st_closing
    227 };
    228 
    229 /* HF Client control block */
    230 tBTA_HF_CLIENT_CB  bta_hf_client_cb;
    231 
    232 /*******************************************************************************
    233 **
    234 ** Function         bta_hf_client_scb_init
    235 **
    236 ** Description      Initialize an HF_Client service control block.
    237 **
    238 **
    239 ** Returns          void
    240 **
    241 *******************************************************************************/
    242 void bta_hf_client_scb_init(void)
    243 {
    244     APPL_TRACE_DEBUG("%s", __FUNCTION__);
    245 
    246     alarm_free(bta_hf_client_cb.scb.collision_timer);
    247     alarm_free(bta_hf_client_cb.scb.at_cb.resp_timer);
    248     alarm_free(bta_hf_client_cb.scb.at_cb.hold_timer);
    249     memset(&bta_hf_client_cb.scb, 0, sizeof(tBTA_HF_CLIENT_SCB));
    250     bta_hf_client_cb.scb.collision_timer =
    251       alarm_new("bta_hf_client.scb_collision_timer");
    252     bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
    253     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    254 }
    255 
    256 /*******************************************************************************
    257 **
    258 ** Function         bta_hf_client_scb_disable
    259 **
    260 ** Description      Disable a service control block.
    261 **
    262 **
    263 ** Returns          void
    264 **
    265 *******************************************************************************/
    266 void bta_hf_client_scb_disable(void)
    267 {
    268     APPL_TRACE_DEBUG("%s", __FUNCTION__);
    269 
    270     bta_hf_client_scb_init();
    271 
    272     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_DISABLE_EVT, NULL);
    273 }
    274 
    275 /*******************************************************************************
    276 **
    277 ** Function         bta_hf_client_resume_open
    278 **
    279 ** Description      Resume opening process.
    280 **
    281 **
    282 ** Returns          void
    283 **
    284 *******************************************************************************/
    285 void bta_hf_client_resume_open (void)
    286 {
    287     APPL_TRACE_DEBUG ("%s", __FUNCTION__);
    288 
    289     /* resume opening process.  */
    290     if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_INIT_ST)
    291     {
    292         bta_hf_client_cb.scb.state = BTA_HF_CLIENT_OPENING_ST;
    293         bta_hf_client_start_open (NULL);
    294     }
    295 }
    296 
    297 /*******************************************************************************
    298 **
    299 ** Function         bta_hf_client_collision_timer_cback
    300 **
    301 ** Description      HF Client connection collision timer callback
    302 **
    303 **
    304 ** Returns          void
    305 **
    306 *******************************************************************************/
    307 static void bta_hf_client_collision_timer_cback(UNUSED_ATTR void *data)
    308 {
    309     APPL_TRACE_DEBUG("%s", __FUNCTION__);
    310 
    311     /* If the peer haven't opened connection, restart opening process */
    312     bta_hf_client_resume_open();
    313 }
    314 
    315 /*******************************************************************************
    316 **
    317 ** Function         bta_hf_client_collision_cback
    318 **
    319 ** Description      Get notified about collision.
    320 **
    321 **
    322 ** Returns          void
    323 **
    324 *******************************************************************************/
    325 void bta_hf_client_collision_cback (tBTA_SYS_CONN_STATUS status, UINT8 id,
    326                                     UINT8 app_id, BD_ADDR peer_addr)
    327 {
    328     UNUSED(status);
    329     UNUSED(app_id);
    330     UNUSED(peer_addr);
    331 
    332     if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPENING_ST)
    333     {
    334         if (id == BTA_ID_SYS)   /* ACL collision */
    335         {
    336             APPL_TRACE_WARNING ("HF Client found collision (ACL) ...");
    337         }
    338         else if (id == BTA_ID_HS)   /* RFCOMM collision */
    339         {
    340             APPL_TRACE_WARNING ("HF Client found collision (RFCOMM) ...");
    341         }
    342         else
    343         {
    344             APPL_TRACE_WARNING ("HF Client found collision (\?\?\?) ...");
    345         }
    346 
    347         bta_hf_client_cb.scb.state = BTA_HF_CLIENT_INIT_ST;
    348 
    349         /* Cancel SDP if it had been started. */
    350         if(bta_hf_client_cb.scb.p_disc_db)
    351         {
    352             (void)SDP_CancelServiceSearch (bta_hf_client_cb.scb.p_disc_db);
    353             bta_hf_client_free_db(NULL);
    354         }
    355 
    356         /* reopen registered server */
    357         /* Collision may be detected before or after we close servers. */
    358         bta_hf_client_start_server();
    359 
    360         /* Start timer to handle connection opening restart */
    361         alarm_set_on_queue(bta_hf_client_cb.scb.collision_timer,
    362                            BTA_HF_CLIENT_COLLISION_TIMER_MS,
    363                            bta_hf_client_collision_timer_cback,
    364                            NULL,
    365                            btu_bta_alarm_queue);
    366     }
    367 }
    368 
    369 /*******************************************************************************
    370 **
    371 ** Function         bta_hf_client_api_enable
    372 **
    373 ** Description      Handle an API enable event.
    374 **
    375 **
    376 ** Returns          void
    377 **
    378 *******************************************************************************/
    379 static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
    380 {
    381     char value[PROPERTY_VALUE_MAX];
    382 
    383     /* initialize control block */
    384     memset(&bta_hf_client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
    385 
    386     /* store callback function */
    387     bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
    388 
    389     /* check if mSBC support enabled */
    390     osi_property_get("ro.bluetooth.hfp.ver", value, "0");
    391     if (strcmp(value,"1.6") == 0)
    392     {
    393        bta_hf_client_cb.msbc_enabled = TRUE;
    394     }
    395 
    396     bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
    397 
    398     /* set same setting as AG does */
    399     BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
    400 
    401     bta_sys_collision_register (BTA_ID_HS, bta_hf_client_collision_cback);
    402 
    403     /* call callback with enable event */
    404     (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_ENABLE_EVT, NULL);
    405 }
    406 
    407 /*******************************************************************************
    408 **
    409 ** Function         bta_hf_client_api_disable
    410 **
    411 ** Description      Handle an API disable event.
    412 **
    413 **
    414 ** Returns          void
    415 **
    416 *******************************************************************************/
    417 static void bta_hf_client_api_disable(tBTA_HF_CLIENT_DATA *p_data)
    418 {
    419     if (!bta_sys_is_register (BTA_ID_HS))
    420     {
    421         APPL_TRACE_ERROR("BTA HF Client is already disabled, ignoring ...");
    422         return;
    423     }
    424 
    425     /* De-register with BTA system manager */
    426     bta_sys_deregister(BTA_ID_HS);
    427 
    428     bta_hf_client_sm_execute(BTA_HF_CLIENT_API_DEREGISTER_EVT, p_data);
    429 
    430     bta_sys_collision_register (BTA_ID_HS, NULL);
    431 }
    432 
    433 /*******************************************************************************
    434 **
    435 ** Function         bta_hf_client_hdl_event
    436 **
    437 ** Description      Data HF Client main event handling function.
    438 **
    439 **
    440 ** Returns          BOOLEAN
    441 **
    442 *******************************************************************************/
    443 BOOLEAN bta_hf_client_hdl_event(BT_HDR *p_msg)
    444 {
    445 #if BTA_HF_CLIENT_DEBUG == TRUE
    446     APPL_TRACE_DEBUG("bta_hf_client_hdl_event %s (0x%x)", bta_hf_client_evt_str(p_msg->event), p_msg->event);
    447 #endif
    448 
    449     switch (p_msg->event)
    450     {
    451         /* handle enable event */
    452         case BTA_HF_CLIENT_API_ENABLE_EVT:
    453             bta_hf_client_api_enable((tBTA_HF_CLIENT_DATA *) p_msg);
    454             break;
    455 
    456         /* handle disable event */
    457         case BTA_HF_CLIENT_API_DISABLE_EVT:
    458             bta_hf_client_api_disable((tBTA_HF_CLIENT_DATA *) p_msg);
    459             break;
    460 
    461         default:
    462                 bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA *) p_msg);
    463             break;
    464     }
    465     return TRUE;
    466 }
    467 
    468 /*******************************************************************************
    469 **
    470 ** Function         bta_hf_client_sm_execute
    471 **
    472 ** Description      State machine event handling function for HF Client
    473 **
    474 **
    475 ** Returns          void
    476 **
    477 *******************************************************************************/
    478 void bta_hf_client_sm_execute(UINT16 event, tBTA_HF_CLIENT_DATA *p_data)
    479 {
    480     tBTA_HF_CLIENT_ST_TBL      state_table;
    481     UINT8               action;
    482     int                 i;
    483 
    484 #if BTA_HF_CLIENT_DEBUG == TRUE
    485     UINT16  in_event = event;
    486     UINT8 in_state =  bta_hf_client_cb.scb.state;
    487 
    488     /* Ignore displaying of AT results when not connected (Ignored in state machine) */
    489     if (bta_hf_client_cb.scb.state == BTA_HF_CLIENT_OPEN_ST)
    490     {
    491         APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
    492                            bta_hf_client_cb.scb.state,
    493                            bta_hf_client_state_str(bta_hf_client_cb.scb.state),
    494                            event, bta_hf_client_evt_str(event));
    495     }
    496 #endif
    497 
    498     event &= 0x00FF;
    499     if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF))
    500     {
    501         APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
    502         return;
    503     }
    504 
    505     /* look up the state table for the current state */
    506     state_table = bta_hf_client_st_tbl[bta_hf_client_cb.scb.state];
    507 
    508     /* set next state */
    509     bta_hf_client_cb.scb.state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
    510 
    511     /* execute action functions */
    512     for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++)
    513     {
    514         if ((action = state_table[event][i]) != BTA_HF_CLIENT_IGNORE)
    515         {
    516             (*bta_hf_client_action[action])(p_data);
    517         }
    518         else
    519         {
    520             break;
    521         }
    522     }
    523 
    524 #if BTA_HF_CLIENT_DEBUG == TRUE
    525     if (bta_hf_client_cb.scb.state != in_state)
    526     {
    527         APPL_TRACE_EVENT("BTA HF Client State Change: [%s] -> [%s] after Event [%s]",
    528                               bta_hf_client_state_str(in_state),
    529                               bta_hf_client_state_str(bta_hf_client_cb.scb.state),
    530                               bta_hf_client_evt_str(in_event));
    531     }
    532 #endif
    533 }
    534 
    535 static void send_post_slc_cmd(void)
    536 {
    537     bta_hf_client_cb.scb.at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
    538 
    539     bta_hf_client_send_at_bia();
    540     bta_hf_client_send_at_ccwa(TRUE);
    541     bta_hf_client_send_at_cmee(TRUE);
    542     bta_hf_client_send_at_cops(FALSE);
    543     bta_hf_client_send_at_btrh(TRUE, 0);
    544     bta_hf_client_send_at_clip(TRUE);
    545 }
    546 
    547 /*******************************************************************************
    548 **
    549 ** Function         bta_hf_client_slc_seq
    550 **
    551 ** Description      Handles AT commands sequence required for SLC creation
    552 **
    553 **
    554 ** Returns          void
    555 **
    556 *******************************************************************************/
    557 void bta_hf_client_slc_seq(BOOLEAN error)
    558 {
    559     APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u", bta_hf_client_cb.scb.at_cb.current_cmd);
    560 
    561     if (error) {
    562         /* SLC establishment error, sent close rfcomm event */
    563         APPL_TRACE_ERROR("HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
    564                 bta_hf_client_cb.scb.at_cb.current_cmd);
    565 
    566         bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
    567         return;
    568     }
    569 
    570     if (bta_hf_client_cb.scb.svc_conn)
    571         return;
    572 
    573     switch (bta_hf_client_cb.scb.at_cb.current_cmd)
    574     {
    575     case BTA_HF_CLIENT_AT_NONE:
    576         bta_hf_client_send_at_brsf();
    577         break;
    578 
    579     case BTA_HF_CLIENT_AT_BRSF:
    580         if ((bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_CODEC)
    581                 && (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_CODEC))
    582         {
    583             bta_hf_client_send_at_bac();
    584             break;
    585         }
    586 
    587         bta_hf_client_send_at_cind(FALSE);
    588         break;
    589 
    590     case BTA_HF_CLIENT_AT_BAC:
    591         bta_hf_client_send_at_cind(FALSE);
    592         break;
    593 
    594     case BTA_HF_CLIENT_AT_CIND:
    595         bta_hf_client_send_at_cind(TRUE);
    596         break;
    597 
    598     case BTA_HF_CLIENT_AT_CIND_STATUS:
    599         bta_hf_client_send_at_cmer(TRUE);
    600         break;
    601 
    602     case BTA_HF_CLIENT_AT_CMER:
    603         if (bta_hf_client_cb.scb.peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY
    604                && bta_hf_client_cb.scb.features & BTA_HF_CLIENT_FEAT_3WAY)
    605         {
    606             bta_hf_client_send_at_chld('?', 0);
    607         }
    608         else
    609         {
    610             bta_hf_client_svc_conn_open(NULL);
    611             send_post_slc_cmd();
    612         }
    613         break;
    614 
    615     case BTA_HF_CLIENT_AT_CHLD:
    616         bta_hf_client_svc_conn_open(NULL);
    617         send_post_slc_cmd();
    618         break;
    619 
    620     default:
    621         /* If happen there is a bug in SLC creation procedure... */
    622         APPL_TRACE_ERROR("HFPClient: Failed to create SLCdue to unexpected AT command, disconnecting (%u)",
    623                             bta_hf_client_cb.scb.at_cb.current_cmd);
    624 
    625         bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, NULL);
    626         break;
    627     }
    628 }
    629 
    630 #if BTA_HF_CLIENT_DEBUG == TRUE
    631 
    632 #ifndef CASE_RETURN_STR
    633 #define CASE_RETURN_STR(const) case const: return #const;
    634 #endif
    635 
    636 static char *bta_hf_client_evt_str(UINT16 event)
    637 {
    638     switch (event)
    639     {
    640     CASE_RETURN_STR(BTA_HF_CLIENT_API_REGISTER_EVT)
    641     CASE_RETURN_STR(BTA_HF_CLIENT_API_DEREGISTER_EVT)
    642     CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
    643     CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
    644     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
    645     CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
    646     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
    647     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
    648     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
    649     CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
    650     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
    651     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
    652     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
    653     CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
    654     CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
    655     CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
    656     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
    657     CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
    658     CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
    659     default:
    660         return "Unknown HF Client Event";
    661     }
    662 }
    663 
    664 static char *bta_hf_client_state_str(UINT8 state)
    665 {
    666     switch (state)
    667     {
    668     CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
    669     CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
    670     CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
    671     CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
    672     default:
    673         return "Unknown HF Client State";
    674     }
    675 }
    676 #endif
    677