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