Home | History | Annotate | Download | only in ag
      1 /******************************************************************************
      2  *
      3  *  Copyright 2003-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file contains action functions for the audio gateway.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <cstring>
     26 
     27 #include "bta_ag_api.h"
     28 #include "bta_ag_int.h"
     29 #include "bta_api.h"
     30 #include "bta_dm_api.h"
     31 #include "bta_sys.h"
     32 #include "btif_config.h"
     33 #include "l2c_api.h"
     34 #include "osi/include/osi.h"
     35 #include "port_api.h"
     36 #include "utl.h"
     37 
     38 /*****************************************************************************
     39  *  Constants
     40  ****************************************************************************/
     41 
     42 /* maximum length of data to read from RFCOMM */
     43 #define BTA_AG_RFC_READ_MAX 512
     44 
     45 /* maximum AT command length */
     46 #define BTA_AG_CMD_MAX 512
     47 
     48 const uint16_t bta_ag_uuid[BTA_AG_NUM_IDX] = {
     49     UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, UUID_SERVCLASS_AG_HANDSFREE};
     50 
     51 const uint8_t bta_ag_sec_id[BTA_AG_NUM_IDX] = {BTM_SEC_SERVICE_HEADSET_AG,
     52                                                BTM_SEC_SERVICE_AG_HANDSFREE};
     53 
     54 const tBTA_SERVICE_ID bta_ag_svc_id[BTA_AG_NUM_IDX] = {BTA_HSP_SERVICE_ID,
     55                                                        BTA_HFP_SERVICE_ID};
     56 
     57 const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] = {
     58     BTA_HSP_SERVICE_MASK, BTA_HFP_SERVICE_MASK};
     59 
     60 typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB* p_scb, uint16_t cmd,
     61                                     uint8_t arg_type, char* p_arg,
     62                                     int16_t int_arg);
     63 
     64 const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] = {
     65     bta_ag_at_hsp_cback, bta_ag_at_hfp_cback};
     66 
     67 /*******************************************************************************
     68  *
     69  * Function         bta_ag_cback_open
     70  *
     71  * Description      Send open callback event to application.
     72  *
     73  *
     74  * Returns          void
     75  *
     76  ******************************************************************************/
     77 static void bta_ag_cback_open(tBTA_AG_SCB* p_scb, const RawAddress& bd_addr,
     78                               tBTA_AG_STATUS status) {
     79   tBTA_AG_OPEN open = {};
     80 
     81   /* call app callback with open event */
     82   open.hdr.handle = bta_ag_scb_to_idx(p_scb);
     83   open.hdr.app_id = p_scb->app_id;
     84   open.status = status;
     85   open.service_id = bta_ag_svc_id[p_scb->conn_service];
     86   open.bd_addr = bd_addr;
     87 
     88   (*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG*)&open);
     89 }
     90 
     91 /*******************************************************************************
     92  *
     93  * Function         bta_ag_register
     94  *
     95  * Description      This function initializes values of the AG cb and sets up
     96  *                  the SDP record for the services.
     97  *
     98  *
     99  * Returns          void
    100  *
    101  ******************************************************************************/
    102 void bta_ag_register(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    103   /* initialize control block */
    104   p_scb->reg_services = data.api_register.services;
    105   p_scb->serv_sec_mask = data.api_register.sec_mask;
    106   p_scb->features = data.api_register.features;
    107   p_scb->app_id = data.api_register.app_id;
    108 
    109   /* create SDP records */
    110   bta_ag_create_records(p_scb, data);
    111 
    112   /* start RFCOMM servers */
    113   bta_ag_start_servers(p_scb, p_scb->reg_services);
    114 
    115   /* call app callback with register event */
    116   tBTA_AG_REGISTER reg = {};
    117   reg.hdr.handle = bta_ag_scb_to_idx(p_scb);
    118   reg.hdr.app_id = p_scb->app_id;
    119   reg.status = BTA_AG_SUCCESS;
    120   (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG*)&reg);
    121 }
    122 
    123 /*******************************************************************************
    124  *
    125  * Function         bta_ag_deregister
    126  *
    127  * Description      This function removes the sdp records, closes the RFCOMM
    128  *                  servers, and deallocates the service control block.
    129  *
    130  *
    131  * Returns          void
    132  *
    133  ******************************************************************************/
    134 void bta_ag_deregister(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    135   /* set dealloc */
    136   p_scb->dealloc = true;
    137 
    138   /* remove sdp records */
    139   bta_ag_del_records(p_scb);
    140 
    141   /* remove rfcomm servers */
    142   bta_ag_close_servers(p_scb, p_scb->reg_services);
    143 
    144   /* dealloc */
    145   bta_ag_scb_dealloc(p_scb);
    146 }
    147 
    148 /*******************************************************************************
    149  *
    150  * Function         bta_ag_start_dereg
    151  *
    152  * Description      Start a deregister event.
    153  *
    154  *
    155  * Returns          void
    156  *
    157  ******************************************************************************/
    158 void bta_ag_start_dereg(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    159   /* set dealloc */
    160   p_scb->dealloc = true;
    161 
    162   /* remove sdp records */
    163   bta_ag_del_records(p_scb);
    164 }
    165 
    166 /*******************************************************************************
    167  *
    168  * Function         bta_ag_start_open
    169  *
    170  * Description      This starts an AG open.
    171  *
    172  *
    173  * Returns          void
    174  *
    175  ******************************************************************************/
    176 void bta_ag_start_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    177   RawAddress pending_bd_addr = {};
    178 
    179   /* store parameters */
    180   p_scb->peer_addr = data.api_open.bd_addr;
    181   p_scb->cli_sec_mask = data.api_open.sec_mask;
    182   p_scb->open_services = p_scb->reg_services;
    183 
    184   /* Check if RFCOMM has any incoming connection to avoid collision. */
    185   if (PORT_IsOpening(pending_bd_addr)) {
    186     /* Let the incoming connection goes through.                        */
    187     /* Issue collision for this scb for now.                            */
    188     /* We will decide what to do when we find incoming connetion later. */
    189     bta_ag_collision_cback(0, BTA_ID_AG, 0, p_scb->peer_addr);
    190     return;
    191   }
    192 
    193   /* close servers */
    194   bta_ag_close_servers(p_scb, p_scb->reg_services);
    195 
    196   /* set role */
    197   p_scb->role = BTA_AG_INT;
    198 
    199   /* do service search */
    200   bta_ag_do_disc(p_scb, p_scb->open_services);
    201 }
    202 
    203 /*******************************************************************************
    204  *
    205  * Function         bta_ag_disc_int_res
    206  *
    207  * Description      This function handles a discovery result when initiator.
    208  *
    209  *
    210  * Returns          void
    211  *
    212  ******************************************************************************/
    213 void bta_ag_disc_int_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    214   uint16_t event = BTA_AG_DISC_FAIL_EVT;
    215 
    216   APPL_TRACE_DEBUG("bta_ag_disc_int_res: Status: %d", data.disc_result.status);
    217 
    218   /* if found service */
    219   if (data.disc_result.status == SDP_SUCCESS ||
    220       data.disc_result.status == SDP_DB_FULL) {
    221     /* get attributes */
    222     if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services)) {
    223       /* set connected service */
    224       p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services);
    225 
    226       /* send ourselves sdp ok event */
    227       event = BTA_AG_DISC_OK_EVT;
    228     }
    229   }
    230 
    231   /* free discovery db */
    232   bta_ag_free_db(p_scb, data);
    233 
    234   /* if service not found check if we should search for other service */
    235   if ((event == BTA_AG_DISC_FAIL_EVT) &&
    236       (data.disc_result.status == SDP_SUCCESS ||
    237        data.disc_result.status == SDP_DB_FULL ||
    238        data.disc_result.status == SDP_NO_RECS_MATCH)) {
    239     if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) &&
    240         (p_scb->open_services & BTA_HSP_SERVICE_MASK)) {
    241       /* search for HSP */
    242       p_scb->open_services &= ~BTA_HFP_SERVICE_MASK;
    243       bta_ag_do_disc(p_scb, p_scb->open_services);
    244     } else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) &&
    245                (p_scb->hsp_version == HSP_VERSION_1_2)) {
    246       /* search for UUID_SERVCLASS_HEADSET instead */
    247       p_scb->hsp_version = HSP_VERSION_1_0;
    248       bta_ag_do_disc(p_scb, p_scb->open_services);
    249     } else {
    250       /* send ourselves sdp ok/fail event */
    251       bta_ag_sm_execute(p_scb, event, data);
    252     }
    253   } else {
    254     /* send ourselves sdp ok/fail event */
    255     bta_ag_sm_execute(p_scb, event, data);
    256   }
    257 }
    258 
    259 /*******************************************************************************
    260  *
    261  * Function         bta_ag_disc_acp_res
    262  *
    263  * Description      This function handles a discovery result when acceptor.
    264  *
    265  *
    266  * Returns          void
    267  *
    268  ******************************************************************************/
    269 void bta_ag_disc_acp_res(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    270   /* if found service */
    271   if (data.disc_result.status == SDP_SUCCESS ||
    272       data.disc_result.status == SDP_DB_FULL) {
    273     /* get attributes */
    274     bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
    275   }
    276 
    277   /* free discovery db */
    278   bta_ag_free_db(p_scb, data);
    279 }
    280 
    281 /*******************************************************************************
    282  *
    283  * Function         bta_ag_disc_fail
    284  *
    285  * Description      This function handles a discovery failure.
    286  *
    287  *
    288  * Returns          void
    289  *
    290  ******************************************************************************/
    291 void bta_ag_disc_fail(tBTA_AG_SCB* p_scb,
    292                       UNUSED_ATTR const tBTA_AG_DATA& data) {
    293   /* reopen registered servers */
    294   bta_ag_start_servers(p_scb, p_scb->reg_services);
    295 
    296   /* reinitialize stuff */
    297 
    298   /* clear the remote BD address */
    299   RawAddress peer_addr = p_scb->peer_addr;
    300   p_scb->peer_addr = RawAddress::kEmpty;
    301 
    302   /* call open cback w. failure */
    303   bta_ag_cback_open(p_scb, peer_addr, BTA_AG_FAIL_SDP);
    304 }
    305 
    306 /*******************************************************************************
    307  *
    308  * Function         bta_ag_open_fail
    309  *
    310  * Description      open connection failed.
    311  *
    312  *
    313  * Returns          void
    314  *
    315  ******************************************************************************/
    316 void bta_ag_open_fail(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    317   /* call open cback w. failure */
    318   bta_ag_cback_open(p_scb, data.api_open.bd_addr, BTA_AG_FAIL_RESOURCES);
    319 }
    320 
    321 /*******************************************************************************
    322  *
    323  * Function         bta_ag_rfc_fail
    324  *
    325  * Description      RFCOMM connection failed.
    326  *
    327  *
    328  * Returns          void
    329  *
    330  ******************************************************************************/
    331 void bta_ag_rfc_fail(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
    332   RawAddress peer_addr = p_scb->peer_addr;
    333   /* reinitialize stuff */
    334   p_scb->conn_handle = 0;
    335   p_scb->conn_service = 0;
    336   p_scb->peer_features = 0;
    337   p_scb->peer_codecs = BTA_AG_CODEC_CVSD;
    338   p_scb->sco_codec = BTA_AG_CODEC_CVSD;
    339   p_scb->role = 0;
    340   p_scb->svc_conn = false;
    341   p_scb->hsp_version = HSP_VERSION_1_2;
    342   /*Clear the BD address*/
    343   p_scb->peer_addr = RawAddress::kEmpty;
    344 
    345   /* reopen registered servers */
    346   bta_ag_start_servers(p_scb, p_scb->reg_services);
    347 
    348   /* call open cback w. failure */
    349   bta_ag_cback_open(p_scb, peer_addr, BTA_AG_FAIL_RFCOMM);
    350 }
    351 
    352 /*******************************************************************************
    353  *
    354  * Function         bta_ag_rfc_close
    355  *
    356  * Description      RFCOMM connection closed.
    357  *
    358  *
    359  * Returns          void
    360  *
    361  ******************************************************************************/
    362 void bta_ag_rfc_close(tBTA_AG_SCB* p_scb,
    363                       UNUSED_ATTR const tBTA_AG_DATA& data) {
    364   tBTA_AG_CLOSE close = {};
    365   tBTA_SERVICE_MASK services;
    366   int i, num_active_conn = 0;
    367 
    368   /* reinitialize stuff */
    369   p_scb->conn_service = 0;
    370   p_scb->peer_features = 0;
    371   p_scb->peer_codecs = BTA_AG_CODEC_CVSD;
    372   p_scb->sco_codec = BTA_AG_CODEC_CVSD;
    373   /* Clear these flags upon SLC teardown */
    374   p_scb->codec_updated = false;
    375   p_scb->codec_fallback = false;
    376   p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
    377   p_scb->role = 0;
    378   p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    379   p_scb->svc_conn = false;
    380   p_scb->hsp_version = HSP_VERSION_1_2;
    381   bta_ag_at_reinit(&p_scb->at_cb);
    382 
    383   for (auto& peer_hf_indicator : p_scb->peer_hf_indicators) {
    384     peer_hf_indicator = {};
    385   }
    386   for (auto& local_hf_indicator : p_scb->local_hf_indicators) {
    387     local_hf_indicator = {};
    388   }
    389 
    390   /* stop timers */
    391   alarm_cancel(p_scb->ring_timer);
    392   alarm_cancel(p_scb->codec_negotiation_timer);
    393 
    394   close.hdr.handle = bta_ag_scb_to_idx(p_scb);
    395   close.hdr.app_id = p_scb->app_id;
    396   close.bd_addr = p_scb->peer_addr;
    397 
    398   bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    399 
    400   if (bta_ag_get_active_device() == p_scb->peer_addr) {
    401     bta_clear_active_device();
    402   }
    403 
    404   /* call close cback */
    405   (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG*)&close);
    406 
    407   /* if not deregistering (deallocating) reopen registered servers */
    408   if (!p_scb->dealloc) {
    409     /* Clear peer bd_addr so instance can be reused */
    410     p_scb->peer_addr = RawAddress::kEmpty;
    411 
    412     /* start only unopened server */
    413     services = p_scb->reg_services;
    414     for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++) {
    415       if (p_scb->serv_handle[i])
    416         services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i));
    417     }
    418     bta_ag_start_servers(p_scb, services);
    419 
    420     p_scb->conn_handle = 0;
    421 
    422     /* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */
    423     bta_ag_sco_shutdown(p_scb, tBTA_AG_DATA::kEmpty);
    424 
    425     /* Check if all the SLCs are down */
    426     for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++) {
    427       if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn)
    428         num_active_conn++;
    429     }
    430 
    431     if (!num_active_conn) {
    432       bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    433     }
    434 
    435   }
    436   /* else close port and deallocate scb */
    437   else {
    438     RFCOMM_RemoveServer(p_scb->conn_handle);
    439     bta_ag_scb_dealloc(p_scb);
    440   }
    441 }
    442 
    443 /*******************************************************************************
    444  *
    445  * Function         bta_ag_rfc_open
    446  *
    447  * Description      Handle RFCOMM channel open.
    448  *
    449  *
    450  * Returns          void
    451  *
    452  ******************************************************************************/
    453 void bta_ag_rfc_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    454   /* initialize AT feature variables */
    455   p_scb->clip_enabled = false;
    456   p_scb->ccwa_enabled = false;
    457   p_scb->cmer_enabled = false;
    458   p_scb->cmee_enabled = false;
    459   p_scb->inband_enabled =
    460       ((p_scb->features & BTA_AG_FEAT_INBAND) == BTA_AG_FEAT_INBAND);
    461   if (p_scb->conn_service == BTA_AG_HFP) {
    462     size_t version_value_size = sizeof(p_scb->peer_version);
    463     if (!btif_config_get_bin(
    464             p_scb->peer_addr.ToString(), HFP_VERSION_CONFIG_KEY,
    465             (uint8_t*)&p_scb->peer_version, &version_value_size)) {
    466       APPL_TRACE_WARNING("%s: Failed read cached peer HFP version for %s",
    467                          __func__, p_scb->peer_addr.ToString().c_str());
    468       p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN;
    469     }
    470     size_t sdp_features_size = sizeof(p_scb->peer_sdp_features);
    471     if (btif_config_get_bin(
    472             p_scb->peer_addr.ToString(), HFP_SDP_FEATURES_CONFIG_KEY,
    473             (uint8_t*)&p_scb->peer_sdp_features, &sdp_features_size)) {
    474       bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
    475       if (!p_scb->received_at_bac && sdp_wbs_support) {
    476         p_scb->codec_updated = true;
    477         p_scb->peer_codecs = BTA_AG_CODEC_CVSD & BTA_AG_CODEC_MSBC;
    478         p_scb->sco_codec = UUID_CODEC_MSBC;
    479       }
    480     } else {
    481       APPL_TRACE_WARNING("%s: Failed read cached peer HFP SDP features for %s",
    482                          __func__, p_scb->peer_addr.ToString().c_str());
    483     }
    484   }
    485 
    486   /* set up AT command interpreter */
    487   p_scb->at_cb.p_at_tbl = bta_ag_at_tbl[p_scb->conn_service];
    488   p_scb->at_cb.p_cmd_cback = bta_ag_at_cback_tbl[p_scb->conn_service];
    489   p_scb->at_cb.p_err_cback = bta_ag_at_err_cback;
    490   p_scb->at_cb.p_user = p_scb;
    491   p_scb->at_cb.cmd_max_len = BTA_AG_CMD_MAX;
    492   bta_ag_at_init(&p_scb->at_cb);
    493 
    494   bta_sys_conn_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    495 
    496   bta_ag_cback_open(p_scb, p_scb->peer_addr, BTA_AG_SUCCESS);
    497 
    498   if (p_scb->conn_service == BTA_AG_HFP) {
    499     /* if hfp start timer for service level conn */
    500     bta_sys_start_timer(p_scb->ring_timer, p_bta_ag_cfg->conn_tout,
    501                         BTA_AG_SVC_TIMEOUT_EVT, bta_ag_scb_to_idx(p_scb));
    502   } else {
    503     /* else service level conn is open */
    504     bta_ag_svc_conn_open(p_scb, data);
    505   }
    506 }
    507 
    508 /*******************************************************************************
    509  *
    510  * Function         bta_ag_rfc_acp_open
    511  *
    512  * Description      Handle RFCOMM channel open when accepting connection.
    513  *
    514  *
    515  * Returns          void
    516  *
    517  ******************************************************************************/
    518 void bta_ag_rfc_acp_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    519   /* set role */
    520   p_scb->role = BTA_AG_ACP;
    521 
    522   APPL_TRACE_DEBUG("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
    523                    p_scb->serv_handle[0], p_scb->serv_handle[1]);
    524 
    525   /* get bd addr of peer */
    526   uint16_t lcid = 0;
    527   RawAddress dev_addr = RawAddress::kEmpty;
    528   int status = PORT_CheckConnection(data.rfc.port_handle, dev_addr, &lcid);
    529   if (status != PORT_SUCCESS) {
    530     LOG(ERROR) << __func__ << ", PORT_CheckConnection returned " << status;
    531     return;
    532   }
    533 
    534   /* Collision Handling */
    535   for (tBTA_AG_SCB& ag_scb : bta_ag_cb.scb) {
    536     // Cancel any pending collision timers
    537     if (ag_scb.in_use && alarm_is_scheduled(ag_scb.collision_timer)) {
    538       VLOG(1) << __func__ << ": cancel collision alarm for "
    539               << ag_scb.peer_addr;
    540       alarm_cancel(ag_scb.collision_timer);
    541       if (dev_addr != ag_scb.peer_addr && p_scb != &ag_scb) {
    542         // Resume outgoing connection if incoming is not on the same device
    543         bta_ag_resume_open(&ag_scb);
    544       }
    545     }
    546     if (dev_addr == ag_scb.peer_addr && p_scb != &ag_scb) {
    547       VLOG(1) << __func__ << ": fail outgoing connection before accepting "
    548               << ag_scb.peer_addr;
    549       // Fail the outgoing connection to clean up any upper layer states
    550       bta_ag_rfc_fail(&ag_scb, tBTA_AG_DATA::kEmpty);
    551       // If client port is opened, close it
    552       if (ag_scb.conn_handle > 0) {
    553         status = RFCOMM_RemoveConnection(ag_scb.conn_handle);
    554         if (status != PORT_SUCCESS) {
    555           LOG(WARNING) << __func__ << ": RFCOMM_RemoveConnection failed for "
    556                        << dev_addr << ", handle "
    557                        << std::to_string(ag_scb.conn_handle) << ", error "
    558                        << status;
    559         }
    560       }
    561     }
    562     VLOG(1) << __func__ << ": dev_addr=" << dev_addr
    563             << ", peer_addr=" << ag_scb.peer_addr
    564             << ", in_use=" << ag_scb.in_use
    565             << ", index=" << bta_ag_scb_to_idx(p_scb);
    566   }
    567 
    568   p_scb->peer_addr = dev_addr;
    569 
    570   /* determine connected service from port handle */
    571   for (int i = 0; i < BTA_AG_NUM_IDX; i++) {
    572     APPL_TRACE_DEBUG(
    573         "bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d", i,
    574         p_scb->serv_handle[i], data.rfc.port_handle);
    575 
    576     if (p_scb->serv_handle[i] == data.rfc.port_handle) {
    577       p_scb->conn_service = i;
    578       p_scb->conn_handle = data.rfc.port_handle;
    579       break;
    580     }
    581   }
    582 
    583   APPL_TRACE_DEBUG("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
    584                    p_scb->conn_service, p_scb->conn_handle);
    585 
    586   /* close any unopened server */
    587   bta_ag_close_servers(
    588       p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service]));
    589 
    590   /* do service discovery to get features */
    591   bta_ag_do_disc(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
    592 
    593   /* continue with common open processing */
    594   bta_ag_rfc_open(p_scb, data);
    595 }
    596 
    597 /*******************************************************************************
    598  *
    599  * Function         bta_ag_rfc_data
    600  *
    601  * Description      Read and process data from RFCOMM.
    602  *
    603  *
    604  * Returns          void
    605  *
    606  ******************************************************************************/
    607 void bta_ag_rfc_data(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
    608   uint16_t len;
    609   char buf[BTA_AG_RFC_READ_MAX] = "";
    610 
    611   APPL_TRACE_DEBUG("%s", __func__);
    612 
    613   /* do the following */
    614   for (;;) {
    615     /* read data from rfcomm; if bad status, we're done */
    616     if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) !=
    617         PORT_SUCCESS) {
    618       LOG(ERROR) << __func__ << ": failed to read data " << p_scb->peer_addr;
    619       break;
    620     }
    621 
    622     /* if no data, we're done */
    623     if (len == 0) {
    624       LOG(WARNING) << __func__ << ": no data for " << p_scb->peer_addr;
    625       break;
    626     }
    627 
    628     /* run AT command interpreter on data */
    629     bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    630     bta_ag_at_parse(&p_scb->at_cb, buf, len);
    631     if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) &&
    632         bta_ag_sco_is_open(p_scb)) {
    633       APPL_TRACE_DEBUG("%s change link policy for SCO", __func__);
    634       bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    635     } else {
    636       bta_sys_idle(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    637     }
    638 
    639     /* no more data to read, we're done */
    640     if (len < BTA_AG_RFC_READ_MAX) {
    641       break;
    642     }
    643   }
    644 }
    645 
    646 /*******************************************************************************
    647  *
    648  * Function         bta_ag_start_close
    649  *
    650  * Description      Start the process of closing SCO and RFCOMM connection.
    651  *
    652  *
    653  * Returns          void
    654  *
    655  ******************************************************************************/
    656 void bta_ag_start_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    657   /* Take the link out of sniff and set L2C idle time to 0 */
    658   bta_dm_pm_active(p_scb->peer_addr);
    659   L2CA_SetIdleTimeoutByBdAddr(p_scb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
    660 
    661   /* if SCO is open close SCO and wait on RFCOMM close */
    662   if (bta_ag_sco_is_open(p_scb)) {
    663     p_scb->post_sco = BTA_AG_POST_SCO_CLOSE_RFC;
    664   } else {
    665     p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    666     bta_ag_rfc_do_close(p_scb, data);
    667   }
    668 
    669   /* always do SCO shutdown to handle all SCO corner cases */
    670   bta_ag_sco_shutdown(p_scb, data);
    671 }
    672 
    673 /*******************************************************************************
    674  *
    675  * Function         bta_ag_post_sco_open
    676  *
    677  * Description      Perform post-SCO open action, if any
    678  *
    679  *
    680  * Returns          void
    681  *
    682  ******************************************************************************/
    683 void bta_ag_post_sco_open(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    684   switch (p_scb->post_sco) {
    685     case BTA_AG_POST_SCO_RING:
    686       bta_ag_send_ring(p_scb, data);
    687       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    688       break;
    689 
    690     case BTA_AG_POST_SCO_CALL_CONN:
    691       bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
    692       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    693       break;
    694 
    695     default:
    696       break;
    697   }
    698 }
    699 
    700 /*******************************************************************************
    701  *
    702  * Function         bta_ag_post_sco_close
    703  *
    704  * Description      Perform post-SCO close action, if any
    705  *
    706  *
    707  * Returns          void
    708  *
    709  ******************************************************************************/
    710 void bta_ag_post_sco_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    711   switch (p_scb->post_sco) {
    712     case BTA_AG_POST_SCO_CLOSE_RFC:
    713       bta_ag_rfc_do_close(p_scb, data);
    714       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    715       break;
    716 
    717     case BTA_AG_POST_SCO_CALL_CONN:
    718       bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
    719       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    720       break;
    721 
    722     case BTA_AG_POST_SCO_CALL_ORIG:
    723       bta_ag_send_call_inds(p_scb, BTA_AG_OUT_CALL_ORIG_RES);
    724       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    725       break;
    726 
    727     case BTA_AG_POST_SCO_CALL_END:
    728       bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
    729       p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    730       break;
    731 
    732     case BTA_AG_POST_SCO_CALL_END_INCALL:
    733       bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
    734 
    735       /* Sending callsetup IND and Ring were defered to after SCO close. */
    736       bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_RES);
    737 
    738       if (bta_ag_inband_enabled(p_scb) &&
    739           !(p_scb->features & BTA_AG_FEAT_NOSCO)) {
    740         p_scb->post_sco = BTA_AG_POST_SCO_RING;
    741         bta_ag_sco_open(p_scb, data);
    742       } else {
    743         p_scb->post_sco = BTA_AG_POST_SCO_NONE;
    744         bta_ag_send_ring(p_scb, data);
    745       }
    746       break;
    747 
    748     default:
    749       break;
    750   }
    751 }
    752 
    753 /*******************************************************************************
    754  *
    755  * Function         bta_ag_svc_conn_open
    756  *
    757  * Description      Service level connection opened
    758  *
    759  *
    760  * Returns          void
    761  *
    762  ******************************************************************************/
    763 void bta_ag_svc_conn_open(tBTA_AG_SCB* p_scb,
    764                           UNUSED_ATTR const tBTA_AG_DATA& data) {
    765   tBTA_AG_CONN evt = {};
    766 
    767   if (!p_scb->svc_conn) {
    768     /* set state variable */
    769     p_scb->svc_conn = true;
    770 
    771     /* Clear AT+BIA mask from previous SLC if any. */
    772     p_scb->bia_masked_out = 0;
    773 
    774     alarm_cancel(p_scb->ring_timer);
    775 
    776     /* call callback */
    777     evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
    778     evt.hdr.app_id = p_scb->app_id;
    779     evt.peer_feat = p_scb->peer_features;
    780     evt.bd_addr = p_scb->peer_addr;
    781     evt.peer_codec = p_scb->peer_codecs;
    782 
    783     if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) ||
    784         (p_scb->callsetup_ind != BTA_AG_CALLSETUP_NONE)) {
    785       bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    786     }
    787     if (bta_ag_get_active_device().IsEmpty()) {
    788       bta_ag_api_set_active_device(p_scb->peer_addr);
    789     }
    790     (*bta_ag_cb.p_cback)(BTA_AG_CONN_EVT, (tBTA_AG*)&evt);
    791   }
    792 }
    793 
    794 /*******************************************************************************
    795  *
    796  * Function         bta_ag_setcodec
    797  *
    798  * Description      Handle API SetCodec
    799  *
    800  *
    801  * Returns          void
    802  *
    803  ******************************************************************************/
    804 void bta_ag_setcodec(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& data) {
    805   tBTA_AG_PEER_CODEC codec_type = data.api_setcodec.codec;
    806   tBTA_AG_VAL val = {};
    807   val.hdr.handle = bta_ag_scb_to_idx(p_scb);
    808 
    809   /* Check if the requested codec type is valid */
    810   if ((codec_type != BTA_AG_CODEC_NONE) && (codec_type != BTA_AG_CODEC_CVSD) &&
    811       (codec_type != BTA_AG_CODEC_MSBC)) {
    812     val.num = codec_type;
    813     val.hdr.status = BTA_AG_FAIL_RESOURCES;
    814     APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d",
    815                      codec_type);
    816     (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val);
    817     return;
    818   }
    819 
    820   if ((p_scb->peer_codecs & codec_type) || (codec_type == BTA_AG_CODEC_NONE) ||
    821       (codec_type == BTA_AG_CODEC_CVSD)) {
    822     p_scb->sco_codec = codec_type;
    823     p_scb->codec_updated = true;
    824     val.num = codec_type;
    825     val.hdr.status = BTA_AG_SUCCESS;
    826     APPL_TRACE_DEBUG("bta_ag_setcodec: Updated codec type %d", codec_type);
    827   } else {
    828     val.num = codec_type;
    829     val.hdr.status = BTA_AG_FAIL_RESOURCES;
    830     APPL_TRACE_ERROR("bta_ag_setcodec error: unsupported codec type %d",
    831                      codec_type);
    832   }
    833 
    834   (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG*)&val);
    835 }
    836 
    837 static void bta_ag_collision_timer_cback(void* data) {
    838   if (data == nullptr) {
    839     LOG(ERROR) << __func__ << ": data should never be null in a timer callback";
    840     return;
    841   }
    842   /* If the peer haven't opened AG connection     */
    843   /* we will restart opening process.             */
    844   bta_ag_resume_open(static_cast<tBTA_AG_SCB*>(data));
    845 }
    846 
    847 void bta_ag_handle_collision(tBTA_AG_SCB* p_scb,
    848                              UNUSED_ATTR const tBTA_AG_DATA& data) {
    849   /* Cancel SDP if it had been started. */
    850   if (p_scb->p_disc_db) {
    851     SDP_CancelServiceSearch(p_scb->p_disc_db);
    852     bta_ag_free_db(p_scb, tBTA_AG_DATA::kEmpty);
    853   }
    854 
    855   /* reopen registered servers */
    856   /* Collision may be detected before or after we close servers. */
    857   if (bta_ag_is_server_closed(p_scb)) {
    858     bta_ag_start_servers(p_scb, p_scb->reg_services);
    859   }
    860 
    861   /* Start timer to han */
    862   alarm_set_on_mloop(p_scb->collision_timer, BTA_AG_COLLISION_TIMEOUT_MS,
    863                      bta_ag_collision_timer_cback, p_scb);
    864 }
    865