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 is the main implementation file for the BTA audio gateway.
22 *
23 ******************************************************************************/
24
25 #include <string>
26 #include <vector>
27
28 #include "bta/ag/bta_ag_int.h"
29 #include "main/shim/dumpsys.h"
30 #include "osi/include/alarm.h"
31 #include "osi/include/compat.h"
32 #include "osi/include/log.h"
33 #include "osi/include/osi.h"
34 #include "stack/include/bt_hdr.h"
35 #include "stack/include/btm_api.h"
36 #include "types/raw_address.h"
37
38 #include <base/logging.h>
39
40 /*****************************************************************************
41 * Constants and types
42 ****************************************************************************/
43 /* state machine states */
44 enum { BTA_AG_INIT_ST, BTA_AG_OPENING_ST, BTA_AG_OPEN_ST, BTA_AG_CLOSING_ST };
45
46 #define CASE_RETURN_STR(const) \
47 case const: \
48 return #const;
49
bta_ag_res_str(tBTA_AG_RES result)50 static const char* bta_ag_res_str(tBTA_AG_RES result) {
51 switch (result) {
52 CASE_RETURN_STR(BTA_AG_SPK_RES)
53 CASE_RETURN_STR(BTA_AG_MIC_RES)
54 CASE_RETURN_STR(BTA_AG_INBAND_RING_RES)
55 CASE_RETURN_STR(BTA_AG_CIND_RES)
56 CASE_RETURN_STR(BTA_AG_BINP_RES)
57 CASE_RETURN_STR(BTA_AG_IND_RES)
58 CASE_RETURN_STR(BTA_AG_BVRA_RES)
59 CASE_RETURN_STR(BTA_AG_CNUM_RES)
60 CASE_RETURN_STR(BTA_AG_BTRH_RES)
61 CASE_RETURN_STR(BTA_AG_CLCC_RES)
62 CASE_RETURN_STR(BTA_AG_COPS_RES)
63 CASE_RETURN_STR(BTA_AG_IN_CALL_RES)
64 CASE_RETURN_STR(BTA_AG_IN_CALL_CONN_RES)
65 CASE_RETURN_STR(BTA_AG_CALL_WAIT_RES)
66 CASE_RETURN_STR(BTA_AG_OUT_CALL_ORIG_RES)
67 CASE_RETURN_STR(BTA_AG_OUT_CALL_ALERT_RES)
68 CASE_RETURN_STR(BTA_AG_OUT_CALL_CONN_RES)
69 CASE_RETURN_STR(BTA_AG_CALL_CANCEL_RES)
70 CASE_RETURN_STR(BTA_AG_END_CALL_RES)
71 CASE_RETURN_STR(BTA_AG_IN_CALL_HELD_RES)
72 CASE_RETURN_STR(BTA_AG_UNAT_RES)
73 CASE_RETURN_STR(BTA_AG_MULTI_CALL_RES)
74 CASE_RETURN_STR(BTA_AG_BIND_RES)
75 CASE_RETURN_STR(BTA_AG_IND_RES_ON_DEMAND)
76 default:
77 return "Unknown AG Result";
78 }
79 }
80
bta_ag_evt_str(uint16_t event)81 static const char* bta_ag_evt_str(uint16_t event) {
82 switch (event) {
83 CASE_RETURN_STR(BTA_AG_API_REGISTER_EVT)
84 CASE_RETURN_STR(BTA_AG_API_DEREGISTER_EVT)
85 CASE_RETURN_STR(BTA_AG_API_OPEN_EVT)
86 CASE_RETURN_STR(BTA_AG_API_CLOSE_EVT)
87 CASE_RETURN_STR(BTA_AG_API_AUDIO_OPEN_EVT)
88 CASE_RETURN_STR(BTA_AG_API_AUDIO_CLOSE_EVT)
89 CASE_RETURN_STR(BTA_AG_API_RESULT_EVT)
90 CASE_RETURN_STR(BTA_AG_API_SETCODEC_EVT)
91 CASE_RETURN_STR(BTA_AG_RFC_OPEN_EVT)
92 CASE_RETURN_STR(BTA_AG_RFC_CLOSE_EVT)
93 CASE_RETURN_STR(BTA_AG_RFC_SRV_CLOSE_EVT)
94 CASE_RETURN_STR(BTA_AG_RFC_DATA_EVT)
95 CASE_RETURN_STR(BTA_AG_SCO_OPEN_EVT)
96 CASE_RETURN_STR(BTA_AG_SCO_CLOSE_EVT)
97 CASE_RETURN_STR(BTA_AG_DISC_ACP_RES_EVT)
98 CASE_RETURN_STR(BTA_AG_DISC_INT_RES_EVT)
99 CASE_RETURN_STR(BTA_AG_DISC_OK_EVT)
100 CASE_RETURN_STR(BTA_AG_DISC_FAIL_EVT)
101 CASE_RETURN_STR(BTA_AG_RING_TIMEOUT_EVT)
102 CASE_RETURN_STR(BTA_AG_SVC_TIMEOUT_EVT)
103 CASE_RETURN_STR(BTA_AG_COLLISION_EVT)
104 default:
105 return "Unknown AG Event";
106 }
107 }
108
bta_ag_state_str(uint8_t state)109 static const char* bta_ag_state_str(uint8_t state) {
110 switch (state) {
111 CASE_RETURN_STR(BTA_AG_INIT_ST)
112 CASE_RETURN_STR(BTA_AG_OPENING_ST)
113 CASE_RETURN_STR(BTA_AG_OPEN_ST)
114 CASE_RETURN_STR(BTA_AG_CLOSING_ST)
115 default:
116 return "Unknown AG State";
117 }
118 }
119
120 /*****************************************************************************
121 * Global data
122 ****************************************************************************/
123
124 /* AG control block */
125 tBTA_AG_CB bta_ag_cb;
126 const tBTA_AG_DATA tBTA_AG_DATA::kEmpty = {};
127
128 /*******************************************************************************
129 *
130 * Function bta_ag_scb_alloc
131 *
132 * Description Allocate an AG service control block.
133 *
134 *
135 * Returns pointer to the scb, or NULL if none could be allocated.
136 *
137 ******************************************************************************/
bta_ag_scb_alloc(void)138 static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
139 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
140 int i;
141
142 for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
143 if (!p_scb->in_use) {
144 /* initialize variables */
145 p_scb->in_use = true;
146 p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
147 p_scb->received_at_bac = false;
148 p_scb->codec_updated = false;
149 p_scb->codec_fallback = false;
150 p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
151 p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
152 p_scb->peer_version = HFP_HSP_VERSION_UNKNOWN;
153 p_scb->hsp_version = HSP_VERSION_1_2;
154 p_scb->peer_sdp_features = 0;
155 /* set up timers */
156 p_scb->ring_timer = alarm_new("bta_ag.scb_ring_timer");
157 p_scb->collision_timer = alarm_new("bta_ag.scb_collision_timer");
158 p_scb->codec_negotiation_timer =
159 alarm_new("bta_ag.scb_codec_negotiation_timer");
160 /* set eSCO mSBC setting to T2 as the preferred */
161 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
162 p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
163 APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
164 break;
165 }
166 }
167
168 if (i == BTA_AG_MAX_NUM_CLIENTS) {
169 /* out of scbs */
170 p_scb = nullptr;
171 LOG_WARN("Out of scbs");
172 }
173 return p_scb;
174 }
175
176 /*******************************************************************************
177 *
178 * Function bta_ag_scb_dealloc
179 *
180 * Description Deallocate a service control block.
181 *
182 *
183 * Returns void
184 *
185 ******************************************************************************/
bta_ag_scb_dealloc(tBTA_AG_SCB * p_scb)186 void bta_ag_scb_dealloc(tBTA_AG_SCB* p_scb) {
187 uint8_t idx;
188 bool allocated = false;
189
190 APPL_TRACE_DEBUG("bta_ag_scb_dealloc %d", bta_ag_scb_to_idx(p_scb));
191
192 /* stop and free timers */
193 alarm_free(p_scb->ring_timer);
194 alarm_free(p_scb->codec_negotiation_timer);
195 alarm_free(p_scb->collision_timer);
196
197 /* initialize control block */
198 *p_scb = {};
199 p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
200
201 /* If all scbs are deallocated, callback with disable event */
202 if (!bta_sys_is_register(BTA_ID_AG)) {
203 for (idx = 0; idx < BTA_AG_MAX_NUM_CLIENTS; idx++) {
204 if (bta_ag_cb.scb[idx].in_use) {
205 allocated = true;
206 break;
207 }
208 }
209
210 if (!allocated) {
211 (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, nullptr);
212 }
213 }
214 }
215
216 /*******************************************************************************
217 *
218 * Function bta_ag_scb_to_idx
219 *
220 * Description Given a pointer to an scb, return its index.
221 *
222 *
223 * Returns Index of scb starting from 1
224 *
225 ******************************************************************************/
bta_ag_scb_to_idx(tBTA_AG_SCB * p_scb)226 uint16_t bta_ag_scb_to_idx(tBTA_AG_SCB* p_scb) {
227 /* use array arithmetic to determine index */
228 return static_cast<uint16_t>(p_scb - bta_ag_cb.scb + 1);
229 }
230
231 /*******************************************************************************
232 *
233 * Function bta_ag_scb_by_idx
234 *
235 * Description Given an scb index return pointer to scb.
236 *
237 *
238 * Returns Pointer to scb or NULL if not allocated.
239 *
240 ******************************************************************************/
bta_ag_scb_by_idx(uint16_t idx)241 tBTA_AG_SCB* bta_ag_scb_by_idx(uint16_t idx) {
242 tBTA_AG_SCB* p_scb;
243
244 /* verify index */
245 if (idx > 0 && idx <= BTA_AG_MAX_NUM_CLIENTS) {
246 p_scb = &bta_ag_cb.scb[idx - 1];
247 if (!p_scb->in_use) {
248 p_scb = nullptr;
249 APPL_TRACE_WARNING("ag scb idx %d not allocated", idx);
250 }
251 } else {
252 p_scb = nullptr;
253 APPL_TRACE_DEBUG("ag scb idx %d out of range", idx);
254 }
255 return p_scb;
256 }
257
258 /*******************************************************************************
259 *
260 * Function bta_ag_service_to_idx
261 *
262 * Description Given a BTA service mask convert to profile index.
263 *
264 *
265 * Returns Profile ndex of scb.
266 *
267 ******************************************************************************/
bta_ag_service_to_idx(tBTA_SERVICE_MASK services)268 uint8_t bta_ag_service_to_idx(tBTA_SERVICE_MASK services) {
269 if (services & BTA_HFP_SERVICE_MASK) {
270 return BTA_AG_HFP;
271 } else {
272 return BTA_AG_HSP;
273 }
274 }
275
276 /*******************************************************************************
277 *
278 * Function bta_ag_idx_by_bdaddr
279 *
280 * Description Find SCB associated with peer BD address.
281 *
282 *
283 * Returns Index of SCB or zero if none found.
284 *
285 ******************************************************************************/
bta_ag_idx_by_bdaddr(const RawAddress * peer_addr)286 uint16_t bta_ag_idx_by_bdaddr(const RawAddress* peer_addr) {
287 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
288 if (peer_addr != nullptr) {
289 for (uint16_t i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
290 if (p_scb->in_use && *peer_addr == p_scb->peer_addr) {
291 return (i + 1);
292 }
293 }
294 }
295
296 /* no scb found */
297 APPL_TRACE_WARNING("No ag scb for peer addr");
298 return 0;
299 }
300
301 /*******************************************************************************
302 *
303 * Function bta_ag_other_scb_open
304 *
305 * Description Check whether any other scb is in open state.
306 *
307 *
308 * Returns true if another scb is in open state, false otherwise.
309 *
310 ******************************************************************************/
bta_ag_other_scb_open(tBTA_AG_SCB * p_curr_scb)311 bool bta_ag_other_scb_open(tBTA_AG_SCB* p_curr_scb) {
312 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
313 for (int i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
314 if (p_scb->in_use && p_scb != p_curr_scb &&
315 p_scb->state == BTA_AG_OPEN_ST) {
316 return true;
317 }
318 }
319 /* no other scb found */
320 LOG_DEBUG("No other ag scb open");
321 return false;
322 }
323
324 /*******************************************************************************
325 *
326 * Function bta_ag_scb_open
327 *
328 * Description Check whether given scb is in open state.
329 *
330 *
331 * Returns true if scb is in open state, false otherwise.
332 *
333 ******************************************************************************/
bta_ag_scb_open(tBTA_AG_SCB * p_curr_scb)334 bool bta_ag_scb_open(tBTA_AG_SCB* p_curr_scb) {
335 return p_curr_scb && p_curr_scb->in_use &&
336 p_curr_scb->state == BTA_AG_OPEN_ST;
337 }
338
339 /*******************************************************************************
340 *
341 * Function bta_ag_collision_cback
342 *
343 * Description Get notified about collision.
344 *
345 *
346 * Returns void
347 *
348 ******************************************************************************/
bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,uint8_t id,UNUSED_ATTR uint8_t app_id,const RawAddress & peer_addr)349 void bta_ag_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status, uint8_t id,
350 UNUSED_ATTR uint8_t app_id,
351 const RawAddress& peer_addr) {
352 /* Check if we have opening scb for the peer device. */
353 uint16_t handle = bta_ag_idx_by_bdaddr(&peer_addr);
354 tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
355
356 if (p_scb && (p_scb->state == BTA_AG_OPENING_ST)) {
357 if (id == BTA_ID_SYS) {
358 LOG(WARNING) << __func__ << ": AG found collision (ACL) for handle "
359 << unsigned(handle) << " device " << peer_addr;
360 } else if (id == BTA_ID_AG) {
361 LOG(WARNING) << __func__ << ": AG found collision (RFCOMM) for handle "
362 << unsigned(handle) << " device " << peer_addr;
363 } else {
364 LOG(WARNING) << __func__ << ": AG found collision (UNKNOWN) for handle "
365 << unsigned(handle) << " device " << peer_addr;
366 }
367 bta_ag_sm_execute(p_scb, BTA_AG_COLLISION_EVT, tBTA_AG_DATA::kEmpty);
368 }
369 }
370
371 /*******************************************************************************
372 *
373 * Function bta_ag_resume_open
374 *
375 * Description Resume opening process.
376 *
377 *
378 * Returns void
379 *
380 ******************************************************************************/
bta_ag_resume_open(tBTA_AG_SCB * p_scb)381 void bta_ag_resume_open(tBTA_AG_SCB* p_scb) {
382 if (p_scb->state == BTA_AG_INIT_ST) {
383 LOG(INFO) << __func__ << ": Resume connection to " << p_scb->peer_addr
384 << ", handle" << bta_ag_scb_to_idx(p_scb);
385 tBTA_AG_DATA open_data = {.api_open = {.bd_addr = p_scb->peer_addr}};
386 bta_ag_sm_execute(p_scb, BTA_AG_API_OPEN_EVT, open_data);
387 } else {
388 VLOG(1) << __func__ << ": device " << p_scb->peer_addr
389 << " is already in state " << std::to_string(p_scb->state);
390 }
391 }
392
393 /*******************************************************************************
394 *
395 * Function bta_ag_api_enable
396 *
397 * Description Handle an API enable event.
398 *
399 *
400 * Returns void
401 *
402 ******************************************************************************/
bta_ag_api_enable(tBTA_AG_CBACK * p_cback)403 void bta_ag_api_enable(tBTA_AG_CBACK* p_cback) {
404 /* initialize control block */
405 LOG_INFO("AG api enable");
406 for (tBTA_AG_SCB& scb : bta_ag_cb.scb) {
407 alarm_free(scb.ring_timer);
408 alarm_free(scb.codec_negotiation_timer);
409 alarm_free(scb.collision_timer);
410 scb = {};
411 }
412
413 /* store callback function */
414 bta_ag_cb.p_cback = p_cback;
415
416 /* call init call-out */
417 BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
418
419 bta_sys_collision_register(BTA_ID_AG, bta_ag_collision_cback);
420
421 /* call callback with enable event */
422 (*bta_ag_cb.p_cback)(BTA_AG_ENABLE_EVT, nullptr);
423 }
424
425 /*******************************************************************************
426 *
427 * Function bta_ag_api_disable
428 *
429 * Description Handle an API disable event.
430 *
431 *
432 * Returns void
433 *
434 ******************************************************************************/
bta_ag_api_disable()435 void bta_ag_api_disable() {
436 /* deregister all scbs in use */
437 tBTA_AG_SCB* p_scb = &bta_ag_cb.scb[0];
438 bool do_dereg = false;
439 int i;
440
441 if (!bta_sys_is_register(BTA_ID_AG)) {
442 APPL_TRACE_ERROR("BTA AG is already disabled, ignoring ...");
443 return;
444 }
445
446 /* De-register with BTA system manager */
447 bta_sys_deregister(BTA_ID_AG);
448
449 for (i = 0; i < BTA_AG_MAX_NUM_CLIENTS; i++, p_scb++) {
450 if (p_scb->in_use) {
451 bta_ag_sm_execute(p_scb, BTA_AG_API_DEREGISTER_EVT, tBTA_AG_DATA::kEmpty);
452 do_dereg = true;
453 }
454 }
455
456 if (!do_dereg) {
457 /* Done, send callback evt to app */
458 (*bta_ag_cb.p_cback)(BTA_AG_DISABLE_EVT, nullptr);
459 }
460
461 bta_sys_collision_register(BTA_ID_AG, nullptr);
462 }
463
464 /*******************************************************************************
465 *
466 * Function bta_ag_api_register
467 *
468 * Description Handle an API event registers a new service.
469 *
470 *
471 * Returns void
472 *
473 ******************************************************************************/
bta_ag_api_register(tBTA_SERVICE_MASK services,tBTA_AG_FEAT features,const std::vector<std::string> & service_names,uint8_t app_id)474 void bta_ag_api_register(tBTA_SERVICE_MASK services, tBTA_AG_FEAT features,
475 const std::vector<std::string>& service_names,
476 uint8_t app_id) {
477 tBTA_AG_SCB* p_scb = bta_ag_scb_alloc();
478 LOG_DEBUG("bta_ag_api_register: p_scb allocation %s",
479 p_scb == nullptr ? "failed" : "success");
480 if (p_scb) {
481 tBTA_AG_DATA data = {};
482 data.api_register.features = features;
483 data.api_register.services = services;
484 data.api_register.app_id = app_id;
485 for (int i = 0; i < BTA_AG_NUM_IDX; i++) {
486 if (!service_names[i].empty()) {
487 strlcpy(data.api_register.p_name[i], service_names[i].c_str(),
488 BTA_SERVICE_NAME_LEN);
489 } else {
490 data.api_register.p_name[i][0] = 0;
491 }
492 }
493 bta_ag_sm_execute(p_scb, BTA_AG_API_REGISTER_EVT, data);
494 } else {
495 tBTA_AG bta_ag = {};
496 bta_ag.reg.status = BTA_AG_FAIL_RESOURCES;
497 (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, &bta_ag);
498 }
499 }
500
501 /*******************************************************************************
502 *
503 * Function bta_ag_api_result
504 *
505 * Description Handle an API result event.
506 *
507 *
508 * Returns void
509 *
510 ******************************************************************************/
bta_ag_api_result(uint16_t handle,tBTA_AG_RES result,const tBTA_AG_RES_DATA & result_data)511 void bta_ag_api_result(uint16_t handle, tBTA_AG_RES result,
512 const tBTA_AG_RES_DATA& result_data) {
513 tBTA_AG_DATA event_data = {};
514 event_data.api_result.result = result;
515 event_data.api_result.data = result_data;
516 tBTA_AG_SCB* p_scb;
517 if (handle != BTA_AG_HANDLE_ALL) {
518 p_scb = bta_ag_scb_by_idx(handle);
519 if (p_scb) {
520 LOG_DEBUG("Audio gateway event for one client handle:%hu scb:%s", handle,
521 p_scb->ToString().c_str());
522 bta_ag_sm_execute(p_scb, static_cast<uint16_t>(BTA_AG_API_RESULT_EVT),
523 event_data);
524 } else {
525 LOG_WARN(
526 "Received audio gateway event for unknown AG control block "
527 "handle:%hu",
528 handle);
529 }
530 } else {
531 int i;
532 for (i = 0, p_scb = &bta_ag_cb.scb[0]; i < BTA_AG_MAX_NUM_CLIENTS;
533 i++, p_scb++) {
534 if (p_scb->in_use && p_scb->svc_conn) {
535 LOG_DEBUG("Audio gateway event for all clients scb:%s",
536 p_scb->ToString().c_str());
537 bta_ag_sm_execute(p_scb, static_cast<uint16_t>(BTA_AG_API_RESULT_EVT),
538 event_data);
539 }
540 }
541 }
542 }
543
bta_ag_better_state_machine(tBTA_AG_SCB * p_scb,uint16_t event,const tBTA_AG_DATA & data)544 static void bta_ag_better_state_machine(tBTA_AG_SCB* p_scb, uint16_t event,
545 const tBTA_AG_DATA& data) {
546 switch (p_scb->state) {
547 case BTA_AG_INIT_ST:
548 switch (event) {
549 case BTA_AG_API_REGISTER_EVT:
550 bta_ag_register(p_scb, data);
551 break;
552 case BTA_AG_API_DEREGISTER_EVT:
553 bta_ag_deregister(p_scb, data);
554 break;
555 case BTA_AG_API_OPEN_EVT:
556 p_scb->state = BTA_AG_OPENING_ST;
557 bta_ag_start_open(p_scb, data);
558 break;
559 case BTA_AG_RFC_OPEN_EVT:
560 p_scb->state = BTA_AG_OPEN_ST;
561 bta_ag_rfc_acp_open(p_scb, data);
562 bta_ag_sco_listen(p_scb, data);
563 break;
564 case BTA_AG_SCO_OPEN_EVT:
565 LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT");
566 bta_ag_sco_conn_open(p_scb, data);
567 break;
568 case BTA_AG_SCO_CLOSE_EVT:
569 bta_ag_sco_conn_close(p_scb, data);
570 break;
571 case BTA_AG_DISC_ACP_RES_EVT:
572 bta_ag_free_db(p_scb, data);
573 break;
574 default:
575 LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
576 break;
577 }
578 break;
579 case BTA_AG_OPENING_ST:
580 switch (event) {
581 case BTA_AG_API_DEREGISTER_EVT:
582 p_scb->state = BTA_AG_CLOSING_ST;
583 bta_ag_rfc_do_close(p_scb, data);
584 bta_ag_start_dereg(p_scb, data);
585 break;
586 case BTA_AG_API_OPEN_EVT:
587 bta_ag_open_fail(p_scb, data);
588 break;
589 case BTA_AG_API_CLOSE_EVT:
590 p_scb->state = BTA_AG_CLOSING_ST;
591 bta_ag_rfc_do_close(p_scb, data);
592 break;
593 case BTA_AG_RFC_OPEN_EVT:
594 p_scb->state = BTA_AG_OPEN_ST;
595 bta_ag_rfc_open(p_scb, data);
596 bta_ag_sco_listen(p_scb, data);
597 break;
598 case BTA_AG_RFC_CLOSE_EVT:
599 p_scb->state = BTA_AG_INIT_ST;
600 bta_ag_rfc_fail(p_scb, data);
601 break;
602 case BTA_AG_SCO_OPEN_EVT:
603 LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT");
604 bta_ag_sco_conn_open(p_scb, data);
605 break;
606 case BTA_AG_SCO_CLOSE_EVT:
607 bta_ag_sco_conn_close(p_scb, data);
608 break;
609 case BTA_AG_DISC_INT_RES_EVT:
610 bta_ag_disc_int_res(p_scb, data);
611 break;
612 case BTA_AG_DISC_OK_EVT:
613 bta_ag_rfc_do_open(p_scb, data);
614 break;
615 case BTA_AG_DISC_FAIL_EVT:
616 p_scb->state = BTA_AG_INIT_ST;
617 bta_ag_disc_fail(p_scb, data);
618 break;
619 case BTA_AG_COLLISION_EVT:
620 p_scb->state = BTA_AG_INIT_ST;
621 bta_ag_handle_collision(p_scb, data);
622 break;
623 default:
624 LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
625 break;
626 }
627 break;
628 case BTA_AG_OPEN_ST:
629 switch (event) {
630 case BTA_AG_API_DEREGISTER_EVT:
631 p_scb->state = BTA_AG_CLOSING_ST;
632 bta_ag_start_close(p_scb, data);
633 bta_ag_start_dereg(p_scb, data);
634 break;
635 case BTA_AG_API_OPEN_EVT:
636 bta_ag_open_fail(p_scb, data);
637 break;
638 case BTA_AG_API_CLOSE_EVT:
639 p_scb->state = BTA_AG_CLOSING_ST;
640 bta_ag_start_close(p_scb, data);
641 break;
642 case BTA_AG_API_AUDIO_OPEN_EVT:
643 bta_ag_sco_open(p_scb, data);
644 break;
645 case BTA_AG_API_AUDIO_CLOSE_EVT:
646 bta_ag_sco_close(p_scb, data);
647 break;
648 case BTA_AG_API_RESULT_EVT:
649 bta_ag_result(p_scb, data);
650 break;
651 case BTA_AG_API_SETCODEC_EVT:
652 bta_ag_setcodec(p_scb, data);
653 break;
654 case BTA_AG_RFC_CLOSE_EVT:
655 p_scb->state = BTA_AG_INIT_ST;
656 bta_ag_rfc_close(p_scb, data);
657 break;
658 case BTA_AG_RFC_DATA_EVT:
659 bta_ag_rfc_data(p_scb, data);
660 break;
661 case BTA_AG_SCO_OPEN_EVT:
662 LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT");
663 bta_ag_sco_conn_open(p_scb, data);
664 bta_ag_post_sco_open(p_scb, data);
665 break;
666 case BTA_AG_SCO_CLOSE_EVT:
667 bta_ag_sco_conn_close(p_scb, data);
668 bta_ag_post_sco_close(p_scb, data);
669 break;
670 case BTA_AG_DISC_ACP_RES_EVT:
671 bta_ag_disc_acp_res(p_scb, data);
672 break;
673 case BTA_AG_RING_TIMEOUT_EVT:
674 bta_ag_send_ring(p_scb, data);
675 break;
676 case BTA_AG_SVC_TIMEOUT_EVT:
677 p_scb->state = BTA_AG_CLOSING_ST;
678 bta_ag_start_close(p_scb, data);
679 break;
680 default:
681 LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
682 break;
683 }
684 break;
685 case BTA_AG_CLOSING_ST:
686 switch (event) {
687 case BTA_AG_API_DEREGISTER_EVT:
688 bta_ag_start_dereg(p_scb, data);
689 break;
690 case BTA_AG_API_OPEN_EVT:
691 bta_ag_open_fail(p_scb, data);
692 break;
693 case BTA_AG_RFC_CLOSE_EVT:
694 p_scb->state = BTA_AG_INIT_ST;
695 bta_ag_rfc_close(p_scb, data);
696 break;
697 case BTA_AG_SCO_OPEN_EVT:
698 LOG_INFO("Opening sco for EVT BTA_AG_SCO_OPEN_EVT");
699 bta_ag_sco_conn_open(p_scb, data);
700 break;
701 case BTA_AG_SCO_CLOSE_EVT:
702 bta_ag_sco_conn_close(p_scb, data);
703 bta_ag_post_sco_close(p_scb, data);
704 break;
705 case BTA_AG_DISC_ACP_RES_EVT:
706 bta_ag_free_db(p_scb, data);
707 break;
708 case BTA_AG_DISC_INT_RES_EVT:
709 p_scb->state = BTA_AG_INIT_ST;
710 bta_ag_free_db(p_scb, data);
711 break;
712 default:
713 LOG_ERROR("unknown event %d at state %d", event, p_scb->state);
714 break;
715 }
716 break;
717 }
718 }
719
720 /*******************************************************************************
721 *
722 * Function bta_ag_sm_execute
723 *
724 * Description State machine event handling function for AG
725 *
726 *
727 * Returns void
728 *
729 ******************************************************************************/
bta_ag_sm_execute(tBTA_AG_SCB * p_scb,uint16_t event,const tBTA_AG_DATA & data)730 void bta_ag_sm_execute(tBTA_AG_SCB* p_scb, uint16_t event,
731 const tBTA_AG_DATA& data) {
732 uint16_t previous_event = event;
733 uint8_t previous_state = p_scb->state;
734
735 LOG_DEBUG(
736 "Execute AG event handle:0x%04x bd_addr:%s state:%s[0x%02x]"
737 " event:%s[0x%04x] result:%s[0x%02x]",
738 bta_ag_scb_to_idx(p_scb), ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr),
739 bta_ag_state_str(p_scb->state), p_scb->state, bta_ag_evt_str(event),
740 event, bta_ag_res_str(data.api_result.result), data.api_result.result);
741
742 bta_ag_better_state_machine(p_scb, event, data);
743
744 if (p_scb->state != previous_state) {
745 LOG_DEBUG(
746 "State changed handle:0x%04x bd_addr:%s "
747 "state_change:%s[0x%02x]->%s[0x%02x]"
748 " event:%s[0x%04x] result:%s[0x%02x]",
749 bta_ag_scb_to_idx(p_scb), ADDRESS_TO_LOGGABLE_CSTR(p_scb->peer_addr),
750 bta_ag_state_str(previous_state), previous_state,
751 bta_ag_state_str(p_scb->state), p_scb->state,
752 bta_ag_evt_str(previous_event), previous_event,
753 bta_ag_res_str(data.api_result.result), data.api_result.result);
754 }
755 }
756
bta_ag_sm_execute_by_handle(uint16_t handle,uint16_t event,const tBTA_AG_DATA & data)757 void bta_ag_sm_execute_by_handle(uint16_t handle, uint16_t event,
758 const tBTA_AG_DATA& data) {
759 tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(handle);
760 if (p_scb) {
761 LOG_DEBUG("AG state machine event:%s[0x%04x] handle:0x%04x",
762 bta_ag_evt_str(event), event, handle);
763 bta_ag_sm_execute(p_scb, event, data);
764 }
765 }
766
767 /**
768 * Handles event from bta_sys_sendmsg(). It is here to support legacy alarm
769 * implementation that is mainly for timeouts.
770 *
771 * @param p_msg event message
772 * @return True to free p_msg, or False if p_msg is freed within this function
773 */
bta_ag_hdl_event(BT_HDR_RIGID * p_msg)774 bool bta_ag_hdl_event(BT_HDR_RIGID* p_msg) {
775 switch (p_msg->event) {
776 case BTA_AG_RING_TIMEOUT_EVT:
777 case BTA_AG_SVC_TIMEOUT_EVT:
778 bta_ag_sm_execute_by_handle(p_msg->layer_specific, p_msg->event,
779 tBTA_AG_DATA::kEmpty);
780 break;
781 default:
782 LOG(FATAL) << __func__ << ": bad event " << p_msg->event
783 << " layer_specific=" << p_msg->layer_specific;
784 break;
785 }
786 return true;
787 }
788