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