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*)®);
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