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  ******************************************************************************/
bta_ag_cback_open(tBTA_AG_SCB * p_scb,const RawAddress & bd_addr,tBTA_AG_STATUS status)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  ******************************************************************************/
bta_ag_register(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_deregister(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_start_dereg(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_start_open(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_disc_int_res(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_disc_acp_res(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_disc_fail(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_open_fail(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_rfc_fail(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_rfc_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_rfc_open(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_rfc_acp_open(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_rfc_data(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_start_close(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_post_sco_open(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_post_sco_close(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_svc_conn_open(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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  ******************************************************************************/
bta_ag_setcodec(tBTA_AG_SCB * p_scb,const tBTA_AG_DATA & data)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 
bta_ag_collision_timer_cback(void * data)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 
bta_ag_handle_collision(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)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