1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*****************************************************************************
8  *
9  *  Filename:      btc_avk.c
10  *
11  *  Description:   AV implementation
12  *
13  *****************************************************************************/
14 #include "common/bt_target.h"
15 #include <string.h>
16 #include "common/bt_trace.h"
17 #include "common/bt_defs.h"
18 #include "osi/allocator.h"
19 #include "stack/btu.h"
20 #include "bta/bta_av_api.h"
21 #include "btc/btc_dm.h"
22 #include "btc/btc_common.h"
23 #include "btc/btc_manage.h"
24 #include "btc_av.h"
25 #include "btc_avrc.h"
26 #include "btc/btc_util.h"
27 #include "btc/btc_profile_queue.h"
28 #include "btc_a2dp.h"
29 #include "btc_a2dp_control.h"
30 #include "btc_a2dp_sink.h"
31 #include "btc_a2dp_source.h"
32 #include "esp_a2dp_api.h"
33 #include "osi/alarm.h"
34 
35 #if BTC_AV_INCLUDED
36 
37 // global variable to inidcate avrc is initialized with a2dp
38 bool g_av_with_rc;
39 // global variable to indicate a2dp is initialized
40 bool g_a2dp_on_init;
41 // global variable to indicate a2dp is deinitialized
42 bool g_a2dp_on_deinit;
43 // global variable to indicate a2dp source deinitialization is ongoing
44 bool g_a2dp_source_ongoing_deinit;
45 // global variable to indicate a2dp sink deinitialization is ongoing
46 bool g_a2dp_sink_ongoing_deinit;
47 
48 
49 /*****************************************************************************
50 **  Constants & Macros
51 ******************************************************************************/
52 #define BTC_AV_SERVICE_NAME "Advanced Audio"
53 
54 #define BTC_TIMEOUT_AV_OPEN_ON_RC_SECS  2
55 /* Max audio per 3-DH5 EDR packet: 23.2ms
56   jitter buffer: 5(JITTER_BUFFER_WATER_LEVEL) */
57 #define BTC_DELAY_REPORT_DFT_VALUE      1200  // 120ms
58 
59 typedef enum {
60     BTC_AV_STATE_IDLE = 0x0,
61     BTC_AV_STATE_OPENING,
62     BTC_AV_STATE_OPENED,
63     BTC_AV_STATE_STARTED,
64     BTC_AV_STATE_CLOSING
65 } btc_av_state_t;
66 
67 /* Should not need dedicated suspend state as actual actions are no
68    different than open state. Suspend flags are needed however to prevent
69    media task from trying to restart stream during remote suspend or while
70    we are in the process of a local suspend */
71 
72 #define BTC_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
73 #define BTC_AV_FLAG_REMOTE_SUSPEND        0x2
74 #define BTC_AV_FLAG_PENDING_START         0x4
75 #define BTC_AV_FLAG_PENDING_STOP          0x8
76 
77 /*****************************************************************************
78 **  Local type definitions
79 ******************************************************************************/
80 
81 typedef struct {
82     int service_id;
83     tBTA_AV_HNDL bta_handle;
84     bt_bdaddr_t peer_bda;
85     btc_sm_handle_t sm_handle;
86     UINT8 flags;
87     tBTA_AV_EDR edr;
88     UINT8   peer_sep;  /* sep type of peer device */
89 #if BTC_AV_SRC_INCLUDED
90     osi_alarm_t *tle_av_open_on_rc;
91 #endif /* BTC_AV_SRC_INCLUDED */
92 } btc_av_cb_t;
93 
94 typedef struct {
95     bt_bdaddr_t target_bda;
96     uint16_t uuid;
97 } btc_av_connect_req_t;
98 
99 typedef struct {
100     bt_bdaddr_t target_bda;
101 } btc_av_disconn_req_t;
102 
103 /*****************************************************************************
104 **  Static variables
105 ******************************************************************************/
106 
107 #if A2D_DYNAMIC_MEMORY == FALSE
108 static btc_av_cb_t btc_av_cb = {0};
109 #else
110 static btc_av_cb_t *btc_av_cb_ptr = NULL;
111 #define btc_av_cb (*btc_av_cb_ptr)
112 #endif ///A2D_DYNAMIC_MEMORY == FALSE
113 
114 /* both interface and media task needs to be ready to alloc incoming request */
115 #define CHECK_BTAV_INIT() do \
116 { \
117     assert (btc_av_cb.sm_handle != NULL); \
118 } while (0)
119 
120 
121 /* Helper macro to avoid code duplication in the state machine handlers */
122 #define CHECK_RC_EVENT(e, d) \
123     case BTA_AV_RC_OPEN_EVT: \
124     case BTA_AV_RC_CLOSE_EVT: \
125     case BTA_AV_REMOTE_CMD_EVT: \
126     case BTA_AV_VENDOR_CMD_EVT: \
127     case BTA_AV_META_MSG_EVT: \
128     case BTA_AV_RC_FEAT_EVT: \
129     case BTA_AV_REMOTE_RSP_EVT: \
130     { \
131          btc_rc_handler(e, d);\
132     }break; \
133 
134 static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *data);
135 static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *data);
136 static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *data);
137 static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *data);
138 static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *data);
139 static void clean_up(int service_id);
140 
141 #if BTC_AV_SRC_INCLUDED
142 static bt_status_t btc_a2d_src_init(void);
143 static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda);
144 static void btc_a2d_src_deinit(void);
145 #endif /* BTC_AV_SRC_INCLUDED */
146 
147 #if BTC_AV_SINK_INCLUDED
148 static bt_status_t btc_a2d_sink_init(void);
149 static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda);
150 static void btc_a2d_sink_set_delay_value(UINT16 delay_value);
151 static void btc_a2d_sink_get_delay_value(void);
152 static void btc_a2d_sink_deinit(void);
153 #endif /* BTC_AV_SINK_INCLUDED */
154 
155 static const btc_sm_handler_t btc_av_state_handlers[] = {
156     btc_av_state_idle_handler,
157     btc_av_state_opening_handler,
158     btc_av_state_opened_handler,
159     btc_av_state_started_handler,
160     btc_av_state_closing_handler
161 };
162 
163 static void btc_av_event_free_data(btc_msg_t *msg);
164 
165 /*************************************************************************
166 ** Extern functions
167 *************************************************************************/
168 
169 extern tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
170 extern tBTA_AVRC_CO_FUNCTS bta_avrc_cos;
171 /*****************************************************************************
172 ** Local helper functions
173 ******************************************************************************/
btc_a2d_cb_to_app(esp_a2d_cb_event_t event,esp_a2d_cb_param_t * param)174 static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
175 {
176     esp_a2d_cb_t btc_a2d_cb = (esp_a2d_cb_t)btc_profile_cb_get(BTC_PID_A2DP);
177     if (btc_a2d_cb) {
178         btc_a2d_cb(event, param);
179     }
180 }
181 
dump_av_sm_state_name(btc_av_state_t state)182 UNUSED_ATTR static const char *dump_av_sm_state_name(btc_av_state_t state)
183 {
184     switch (state) {
185         CASE_RETURN_STR(BTC_AV_STATE_IDLE)
186         CASE_RETURN_STR(BTC_AV_STATE_OPENING)
187         CASE_RETURN_STR(BTC_AV_STATE_OPENED)
188         CASE_RETURN_STR(BTC_AV_STATE_STARTED)
189         CASE_RETURN_STR(BTC_AV_STATE_CLOSING)
190     default: return "UNKNOWN_STATE";
191     }
192 }
193 
dump_av_sm_event_name(btc_av_sm_event_t event)194 UNUSED_ATTR static const char *dump_av_sm_event_name(btc_av_sm_event_t event)
195 {
196     switch ((int)event) {
197         CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
198         CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
199         CASE_RETURN_STR(BTA_AV_OPEN_EVT)
200         CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
201         CASE_RETURN_STR(BTA_AV_START_EVT)
202         CASE_RETURN_STR(BTA_AV_STOP_EVT)
203         CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
204         CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
205         CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
206         CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
207         CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
208         CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
209         CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
210         CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
211         CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
212         CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
213         CASE_RETURN_STR(BTA_AV_PENDING_EVT)
214         CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
215         CASE_RETURN_STR(BTA_AV_REJECT_EVT)
216         CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
217         CASE_RETURN_STR(BTC_SM_ENTER_EVT)
218         CASE_RETURN_STR(BTC_SM_EXIT_EVT)
219         CASE_RETURN_STR(BTC_AV_CONNECT_REQ_EVT)
220         CASE_RETURN_STR(BTC_AV_DISCONNECT_REQ_EVT)
221         CASE_RETURN_STR(BTC_AV_START_STREAM_REQ_EVT)
222         CASE_RETURN_STR(BTC_AV_STOP_STREAM_REQ_EVT)
223         CASE_RETURN_STR(BTC_AV_SUSPEND_STREAM_REQ_EVT)
224         CASE_RETURN_STR(BTC_AV_SINK_CONFIG_REQ_EVT)
225     default: return "UNKNOWN_EVENT";
226     }
227 }
228 
229 /****************************************************************************
230 **  Local helper functions
231 *****************************************************************************/
232 #if BTC_AV_SRC_INCLUDED
233 /*******************************************************************************
234 **
235 ** Function         btc_initiate_av_open_tmr_hdlr
236 **
237 ** Description      Timer to trigger AV open if the remote headset establishes
238 **                  RC connection w/o AV connection. The timer is needed to IOP
239 **                  with headsets that do establish AV after RC connection.
240 **
241 ** Returns          void
242 **
243 *******************************************************************************/
btc_initiate_av_open_tmr_hdlr(void * arg)244 static void btc_initiate_av_open_tmr_hdlr(void *arg)
245 {
246     UNUSED(arg);
247     BD_ADDR peer_addr;
248     btc_av_connect_req_t connect_req;
249     /* is there at least one RC connection - There should be */
250     if (btc_rc_get_connected_peer(peer_addr)) {
251         BTC_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
252         /* In case of AVRCP connection request, we will initiate SRC connection */
253         memcpy(connect_req.target_bda.address, peer_addr, sizeof(bt_bdaddr_t));
254         connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
255         btc_dispatch_sm_event(BTC_AV_CONNECT_REQ_EVT, &connect_req, sizeof(btc_av_connect_req_t));
256     } else {
257         BTC_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
258     }
259 }
260 #endif /* BTC_AV_SRC_INCLUDED */
261 
262 /*****************************************************************************
263 **  Static functions
264 ******************************************************************************/
btc_report_connection_state(esp_a2d_connection_state_t state,bt_bdaddr_t * bd_addr,int disc_rsn)265 static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr, int disc_rsn)
266 {
267     // todo: add callback for SRC
268     esp_a2d_cb_param_t param;
269     memset(&param, 0, sizeof(esp_a2d_cb_param_t));
270 
271     param.conn_stat.state = state;
272     if (bd_addr) {
273         memcpy(param.conn_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
274     }
275     if (state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) {
276         param.conn_stat.disc_rsn = (disc_rsn == 0) ? ESP_A2D_DISC_RSN_NORMAL :
277                                    ESP_A2D_DISC_RSN_ABNORMAL;
278     }
279     btc_a2d_cb_to_app(ESP_A2D_CONNECTION_STATE_EVT, &param);
280 }
281 
btc_report_audio_state(esp_a2d_audio_state_t state,bt_bdaddr_t * bd_addr)282 static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_addr)
283 {
284     // todo: add callback for SRC
285     esp_a2d_cb_param_t param;
286     memset(&param, 0, sizeof(esp_a2d_cb_param_t));
287 
288     param.audio_stat.state = state;
289     if (bd_addr) {
290         memcpy(param.audio_stat.remote_bda, bd_addr, sizeof(esp_bd_addr_t));
291     }
292     btc_a2d_cb_to_app(ESP_A2D_AUDIO_STATE_EVT, &param);
293 }
294 
295 /*****************************************************************************
296 **
297 ** Function     btc_av_state_idle_handler
298 **
299 ** Description  State managing disconnected AV link
300 **
301 ** Returns      TRUE if event was processed, FALSE otherwise
302 **
303 *******************************************************************************/
304 
btc_av_state_idle_handler(btc_sm_event_t event,void * p_data)305 static BOOLEAN btc_av_state_idle_handler(btc_sm_event_t event, void *p_data)
306 {
307     esp_a2d_cb_param_t param;
308 
309     BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__,
310               dump_av_sm_event_name(event), btc_av_cb.flags);
311 
312     switch (event) {
313     case BTC_SM_ENTER_EVT:
314         /* clear the peer_bda */
315         memset(&btc_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
316         btc_av_cb.flags = 0;
317         btc_av_cb.edr = 0;
318         btc_a2dp_on_idle();
319         break;
320 
321     case BTC_SM_EXIT_EVT:
322         break;
323 
324     case BTA_AV_ENABLE_EVT:
325         break;
326 
327     case BTA_AV_REGISTER_EVT:
328         btc_av_cb.bta_handle = ((tBTA_AV *)p_data)->registr.hndl;
329         break;
330 
331     case BTA_AV_PENDING_EVT:
332     case BTC_AV_CONNECT_REQ_EVT: {
333         if (event == BTC_AV_CONNECT_REQ_EVT) {
334             memcpy(&btc_av_cb.peer_bda, &((btc_av_connect_req_t *)p_data)->target_bda,
335                    sizeof(bt_bdaddr_t));
336             if (g_av_with_rc) {
337                 BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle,
338                         TRUE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid);
339             } else {
340                 BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle,
341                         FALSE, BTA_SEC_AUTHENTICATE, ((btc_av_connect_req_t *)p_data)->uuid);
342             }
343         } else if (event == BTA_AV_PENDING_EVT) {
344             bdcpy(btc_av_cb.peer_bda.address, ((tBTA_AV *)p_data)->pend.bd_addr);
345             UINT16 uuid = (btc_av_cb.service_id == BTA_A2DP_SOURCE_SERVICE_ID) ? UUID_SERVCLASS_AUDIO_SOURCE :
346                 UUID_SERVCLASS_AUDIO_SINK;
347             if (g_av_with_rc) {
348                 BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle,
349                         TRUE, BTA_SEC_AUTHENTICATE, uuid);
350             } else {
351                 BTA_AvOpen(btc_av_cb.peer_bda.address, btc_av_cb.bta_handle,
352                        FALSE, BTA_SEC_AUTHENTICATE, uuid);
353             }
354         }
355         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENING);
356     } break;
357 
358     case BTC_AV_DISCONNECT_REQ_EVT:
359         BTC_TRACE_WARNING("No Link At All.");
360         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &((btc_av_disconn_req_t *)p_data)->target_bda, 0);
361         break;
362 
363     case BTA_AV_RC_OPEN_EVT:
364         /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
365          * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
366          * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
367          * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
368          * headsets, as some headsets initiate the AVRC connection first and then
369          * immediately initiate the AV connection
370          *
371          * TODO: We may need to do this only on an AVRCP Play. FixMe
372          */
373 #if BTC_AV_SRC_INCLUDED
374         BTC_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
375         btc_av_cb.tle_av_open_on_rc = osi_alarm_new("AVconn", btc_initiate_av_open_tmr_hdlr, NULL, BTC_TIMEOUT_AV_OPEN_ON_RC_SECS * 1000);
376         osi_alarm_set(btc_av_cb.tle_av_open_on_rc, BTC_TIMEOUT_AV_OPEN_ON_RC_SECS * 1000);
377 #endif /* BTC_AV_SRC_INCLUDED */
378         btc_rc_handler(event, p_data);
379         break;
380 
381     case BTA_AV_REMOTE_CMD_EVT:
382     case BTA_AV_VENDOR_CMD_EVT:
383     case BTA_AV_META_MSG_EVT:
384     case BTA_AV_RC_FEAT_EVT:
385     case BTA_AV_REMOTE_RSP_EVT:
386         btc_rc_handler(event, (tBTA_AV *)p_data);
387         break;
388 
389     case BTA_AV_RC_CLOSE_EVT:
390 #if BTC_AV_SRC_INCLUDED
391         if (btc_av_cb.tle_av_open_on_rc) {
392             osi_alarm_free(btc_av_cb.tle_av_open_on_rc);
393             btc_av_cb.tle_av_open_on_rc = NULL;
394         }
395 #endif /* BTC_AV_SRC_INCLUDED */
396         btc_rc_handler(event, p_data);
397         break;
398 
399     case BTA_AV_SNK_PSC_CFG_EVT:
400 #if BTC_AV_SINK_INCLUDED
401         param.a2d_psc_cfg_stat.psc_mask = ((tBTA_AV *)p_data)->psc.psc_mask;
402         btc_a2d_cb_to_app(ESP_A2D_SNK_PSC_CFG_EVT, &param);
403 #endif /* BTC_AV_SINK_INCLUDED */
404         break;
405     case BTA_AV_SET_DELAY_VALUE_EVT:
406 #if BTC_AV_SINK_INCLUDED
407         param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
408         param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status;
409         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
410 #endif /* BTC_AV_SINK_INCLUDED */
411         break;
412     case BTA_AV_GET_DELAY_VALUE_EVT:
413 #if BTC_AV_SINK_INCLUDED
414         param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
415         btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, &param);
416 #endif /* BTC_AV_SINK_INCLUDED */
417         break;
418 
419     default:
420         BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
421                  dump_av_sm_event_name(event));
422         return FALSE;
423     }
424 
425     return TRUE;
426 }
427 /*****************************************************************************
428 **
429 ** Function        btc_av_state_opening_handler
430 **
431 ** Description     Intermediate state managing events during establishment
432 **                 of avdtp channel
433 **
434 ** Returns         TRUE if event was processed, FALSE otherwise
435 **
436 *******************************************************************************/
437 
btc_av_state_opening_handler(btc_sm_event_t event,void * p_data)438 static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
439 {
440     esp_a2d_cb_param_t param;
441 
442     BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__,
443               dump_av_sm_event_name(event), btc_av_cb.flags);
444 
445     switch (event) {
446     case BTC_SM_ENTER_EVT:
447         /* inform the application that we are entering connecting state */
448         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_CONNECTING, &(btc_av_cb.peer_bda), 0);
449         break;
450 
451     case BTC_SM_EXIT_EVT:
452         break;
453 
454     case BTA_AV_REJECT_EVT:
455         BTC_TRACE_WARNING(" Received  BTA_AV_REJECT_EVT \n");
456         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), 0);
457         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
458         break;
459 
460     case BTA_AV_OPEN_EVT: {
461         tBTA_AV *p_bta_data = (tBTA_AV *)p_data;
462         esp_a2d_connection_state_t conn_stat;
463         btc_sm_state_t av_state;
464         BTC_TRACE_DEBUG("status:%d, edr 0x%x, peer sep %d\n", p_bta_data->open.status,
465                         p_bta_data->open.edr, p_bta_data->open.sep);
466 
467         if (p_bta_data->open.status == BTA_AV_SUCCESS) {
468             btc_av_cb.edr = p_bta_data->open.edr;
469             btc_av_cb.peer_sep = p_bta_data->open.sep;
470 
471             conn_stat = ESP_A2D_CONNECTION_STATE_CONNECTED;
472             av_state = BTC_AV_STATE_OPENED;
473         } else {
474             BTC_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d\n", p_bta_data->open.status);
475 
476             conn_stat = ESP_A2D_CONNECTION_STATE_DISCONNECTED;
477             av_state = BTC_AV_STATE_IDLE;
478         }
479         /* inform the application of the event */
480         btc_report_connection_state(conn_stat, &(btc_av_cb.peer_bda), 0);
481         /* change state to open/idle based on the status */
482         btc_sm_change_state(btc_av_cb.sm_handle, av_state);
483 
484         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
485             /* if queued PLAY command,  send it now */
486             /* necessary to add this?
487             btc_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
488                                              (p_bta_data->open.status == BTA_AV_SUCCESS));
489             */
490         } else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC &&
491                    (p_bta_data->open.status == BTA_AV_SUCCESS)) {
492             /* Bring up AVRCP connection too if AVRC Initialized */
493             if(g_av_with_rc) {
494                 BTA_AvOpenRc(btc_av_cb.bta_handle);
495             } else {
496                 BTC_TRACE_WARNING("AVRC not Init, not using it.");
497             }
498         }
499         btc_queue_advance();
500     } break;
501 
502     case BTC_AV_SINK_CONFIG_REQ_EVT: {
503         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
504             esp_a2d_cb_param_t param;
505             memcpy(param.audio_cfg.remote_bda, &btc_av_cb.peer_bda, sizeof(esp_bd_addr_t));
506             memcpy(&param.audio_cfg.mcc, p_data, sizeof(esp_a2d_mcc_t));
507             btc_a2d_cb_to_app(ESP_A2D_AUDIO_CFG_EVT, &param);
508         }
509     } break;
510 
511     case BTC_AV_CONNECT_REQ_EVT:
512         // Check for device, if same device which moved to opening then ignore callback
513         if (memcmp ((bt_bdaddr_t *)p_data, &(btc_av_cb.peer_bda),
514                     sizeof(btc_av_cb.peer_bda)) == 0) {
515             BTC_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req\n", __func__);
516             btc_queue_advance();
517             break;
518         } else {
519             BTC_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request\n", __func__);
520             btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t *)p_data, 0);
521             btc_queue_advance();
522             break;
523         }
524 
525     case BTA_AV_PENDING_EVT:
526         // Check for device, if same device which moved to opening then ignore callback
527         if (memcmp (((tBTA_AV *)p_data)->pend.bd_addr, &(btc_av_cb.peer_bda),
528                     sizeof(btc_av_cb.peer_bda)) == 0) {
529             BTC_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req\n", __func__);
530             break;
531         } else {
532             BTC_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request\n", __func__);
533             BTA_AvDisconnect(((tBTA_AV *)p_data)->pend.bd_addr);
534             break;
535         }
536 
537     CHECK_RC_EVENT(event, p_data);
538 
539     case BTA_AV_SNK_PSC_CFG_EVT:
540 #if BTC_AV_SINK_INCLUDED
541         param.a2d_psc_cfg_stat.psc_mask = ((tBTA_AV *)p_data)->psc.psc_mask;
542         btc_a2d_cb_to_app(ESP_A2D_SNK_PSC_CFG_EVT, &param);
543 #endif /* BTC_AV_SINK_INCLUDED */
544         break;
545     case BTA_AV_SET_DELAY_VALUE_EVT:
546 #if BTC_AV_SINK_INCLUDED
547         param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
548         param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status;
549         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
550 #endif /* BTC_AV_SINK_INCLUDED */
551         break;
552 
553     case BTA_AV_GET_DELAY_VALUE_EVT:
554 #if BTC_AV_SINK_INCLUDED
555         param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
556         btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, &param);
557 #endif /* BTC_AV_SINK_INCLUDED */
558         break;
559 
560     default:
561         BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event));
562         return FALSE;
563     }
564     return TRUE;
565 }
566 
567 
568 /*****************************************************************************
569 **
570 ** Function        btc_av_state_closing_handler
571 **
572 ** Description     Intermediate state managing events during closing
573 **                 of avdtp channel
574 **
575 ** Returns         TRUE if event was processed, FALSE otherwise
576 **
577 *******************************************************************************/
578 
btc_av_state_closing_handler(btc_sm_event_t event,void * p_data)579 static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data)
580 {
581     esp_a2d_cb_param_t param;
582 
583     BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__,
584               dump_av_sm_event_name(event), btc_av_cb.flags);
585 
586     switch (event) {
587     case BTC_SM_ENTER_EVT:
588 #if BTC_AV_SRC_INCLUDED
589         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
590             /* immediately stop transmission of frames */
591             btc_a2dp_source_set_tx_flush(TRUE);
592             /* wait for audioflinger to stop a2dp */
593         }
594 #endif /* BTC_AV_SRC_INCLUDED */
595 #if BTC_AV_SINK_INCLUDED
596         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
597             btc_a2dp_sink_set_rx_flush(TRUE);
598         }
599 #endif /* BTC_AV_SINK_INCLUDED */
600         break;
601 
602     case BTA_AV_STOP_EVT:
603     case BTC_AV_STOP_STREAM_REQ_EVT:
604 #if BTC_AV_SRC_INCLUDED
605         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
606             /* immediately flush any pending tx frames while suspend is pending */
607             btc_a2dp_source_set_tx_flush(TRUE);
608         }
609 #endif /* BTC_AV_SRC_INCLUDED */
610 #if BTC_AV_SINK_INCLUDED
611         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
612             btc_a2dp_sink_set_rx_flush(TRUE);
613         }
614 #endif /* BTC_AV_SINK_INCLUDED */
615         btc_a2dp_on_stopped(NULL);
616         break;
617 
618     case BTC_SM_EXIT_EVT:
619         break;
620 
621     case BTA_AV_CLOSE_EVT: {
622         tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
623         /* inform the application that we are disconnecting */
624         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda), close->disc_rsn);
625         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
626         break;
627     }
628 
629     /* Handle the RC_CLOSE event for the cleanup */
630     case BTA_AV_RC_CLOSE_EVT:
631         btc_rc_handler(event, (tBTA_AV *)p_data);
632         break;
633 
634     case BTA_AV_SNK_PSC_CFG_EVT:
635         break;
636     case BTA_AV_SET_DELAY_VALUE_EVT:
637 #if BTC_AV_SINK_INCLUDED
638         param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
639         param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status;
640         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
641 #endif /* BTC_AV_SINK_INCLUDED */
642         break;
643 
644     case BTA_AV_GET_DELAY_VALUE_EVT:
645 #if BTC_AV_SINK_INCLUDED
646         param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
647         btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, &param);
648 #endif /* BTC_AV_SINK_INCLUDED */
649         break;
650 
651     default:
652         BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__, dump_av_sm_event_name(event));
653         return FALSE;
654     }
655     return TRUE;
656 }
657 
658 /*****************************************************************************
659 **
660 ** Function     btc_av_state_opened_handler
661 **
662 ** Description  Handles AV events while AVDTP is in OPEN state
663 **
664 ** Returns      TRUE if event was processed, FALSE otherwise
665 **
666 *******************************************************************************/
btc_av_state_opened_handler(btc_sm_event_t event,void * p_data)667 static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
668 {
669     esp_a2d_cb_param_t param;
670     tBTA_AV *p_av = (tBTA_AV *)p_data;
671 
672     BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__,
673               dump_av_sm_event_name(event), btc_av_cb.flags);
674 
675     if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btc_av_cb.flags & BTC_AV_FLAG_REMOTE_SUSPEND) &&
676             (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) ) {
677         BTC_TRACE_DEBUG("%s: Resetting remote suspend flag on RC PLAY\n", __FUNCTION__);
678         btc_av_cb.flags &= ~BTC_AV_FLAG_REMOTE_SUSPEND;
679     }
680 
681     switch (event) {
682     case BTC_SM_ENTER_EVT:
683         btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_STOP;
684         btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
685         break;
686 
687     case BTC_SM_EXIT_EVT:
688         btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
689         break;
690 
691     case BTC_AV_START_STREAM_REQ_EVT:
692 #if BTC_AV_SRC_INCLUDED
693         if (btc_av_cb.peer_sep != AVDT_TSEP_SRC) {
694             btc_a2dp_source_setup_codec();
695         }
696 #endif  /* BTC_AV_SRC_INCLUDED */
697         BTA_AvStart();
698         btc_av_cb.flags |= BTC_AV_FLAG_PENDING_START;
699         break;
700 
701     case BTA_AV_START_EVT: {
702         BTC_TRACE_DEBUG("BTA_AV_START_EVT status %d, suspending %d, init %d\n",
703                  p_av->start.status, p_av->start.suspending, p_av->start.initiator);
704 
705         if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE)) {
706             return TRUE;
707         }
708 #if BTC_AV_SRC_INCLUDED
709         /* if remote tries to start a2dp when DUT is a2dp source
710          * then suspend. In case a2dp is sink and call is active
711          * then disconnect the AVDTP channel
712          */
713         if (!(btc_av_cb.flags & BTC_AV_FLAG_PENDING_START)) {
714             if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
715                 BTC_TRACE_DEBUG("%s: trigger suspend as remote initiated!!", __FUNCTION__);
716                 btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
717             }
718         }
719         /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
720         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
721             if (btc_a2dp_on_started(&p_av->start,
722                                     ((btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) != 0))) {
723                 /* only clear pending flag after acknowledgement */
724                 btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
725             }
726         }
727 #endif /* BTC_AV_SRC_INCLUDED */
728         /* remain in open state if status failed */
729         if (p_av->start.status != BTA_AV_SUCCESS) {
730             return FALSE;
731         }
732 #if BTC_AV_SINK_INCLUDED
733         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
734             btc_a2dp_sink_set_rx_flush(FALSE); /*  remove flush state, ready for streaming*/
735         }
736 #endif /* BTC_AV_SINK_INCLUDED */
737 #if BTC_AV_SRC_INCLUDED
738         /* change state to started, send acknowledgement if start is pending */
739         if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
740             if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
741                 btc_a2dp_on_started(NULL, TRUE);
742             }
743             /* pending start flag will be cleared when exit current state */
744         }
745 #endif /* BTC_AV_SRC_INCLUDED */
746         /* wait for audio path to open */
747         btc_a2dp_control_datapath_ctrl(BTC_AV_DATAPATH_OPEN_EVT);
748 
749         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_STARTED);
750 
751     } break;
752 
753     case BTC_AV_DISCONNECT_REQ_EVT:
754         BTA_AvClose(btc_av_cb.bta_handle);
755         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) {
756             BTA_AvCloseRc(btc_av_cb.bta_handle);
757         }
758 
759         /* inform the application that we are disconnecting */
760         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0);
761         break;
762 
763     case BTA_AV_CLOSE_EVT: {
764         /* avdtp link is closed */
765         btc_a2dp_on_stopped(NULL);
766         tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
767         /* inform the application that we are disconnected */
768         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda),
769                                     close->disc_rsn);
770 
771         if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
772             btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
773             /* pending start flag will be cleared when exit current state */
774         }
775 
776         /* change state to idle, send acknowledgement if start is pending */
777         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
778 
779         if (g_a2dp_source_ongoing_deinit) {
780             clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
781         } else if (g_a2dp_sink_ongoing_deinit) {
782             clean_up(BTA_A2DP_SINK_SERVICE_ID);
783         }
784         break;
785     }
786 
787     case BTA_AV_RECONFIG_EVT:
788         if ((btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) &&
789                 (p_av->reconfig.status == BTA_AV_SUCCESS)) {
790             BTC_TRACE_WARNING("reconfig done BTA_AVstart()\n");
791             BTA_AvStart();
792         } else if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
793             btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
794             btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
795         }
796         break;
797 
798     case BTC_AV_CONNECT_REQ_EVT:
799         if (memcmp (&((btc_av_connect_req_t *)p_data)->target_bda, &(btc_av_cb.peer_bda),
800                     sizeof(btc_av_cb.peer_bda)) == 0) {
801             BTC_TRACE_DEBUG("%s: Ignore BTC_AVCONNECT_REQ_EVT for same device\n", __func__);
802         } else {
803             BTC_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req\n", __func__);
804             btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED,
805                                         (bt_bdaddr_t *)p_data, ESP_A2D_DISC_RSN_NORMAL);
806         }
807         btc_queue_advance();
808         break;
809 
810     CHECK_RC_EVENT(event, p_data);
811 
812     case BTA_AV_SNK_PSC_CFG_EVT:
813         break;
814     case BTA_AV_SET_DELAY_VALUE_EVT:
815 #if BTC_AV_SINK_INCLUDED
816         param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
817         param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status;
818         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
819 #endif /* BTC_AV_SINK_INCLUDED */
820         break;
821 
822     case BTA_AV_GET_DELAY_VALUE_EVT:
823 #if BTC_AV_SINK_INCLUDED
824         param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
825         btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, &param);
826 #endif /* BTC_AV_SINK_INCLUDED */
827         break;
828 
829     default:
830         BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
831                  dump_av_sm_event_name(event));
832         return FALSE;
833 
834     }
835     return TRUE;
836 }
837 
838 /*****************************************************************************
839 **
840 ** Function     btc_av_state_started_handler
841 **
842 ** Description  Handles AV events while A2DP stream is started
843 **
844 ** Returns      TRUE if event was processed, FALSE otherwise
845 **
846 *******************************************************************************/
847 
btc_av_state_started_handler(btc_sm_event_t event,void * p_data)848 static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
849 {
850     tBTA_AV *p_av = (tBTA_AV *)p_data;
851     esp_a2d_cb_param_t param;
852 
853     BTC_TRACE_DEBUG("%s event: %s flags %x\n", __FUNCTION__,
854               dump_av_sm_event_name(event), btc_av_cb.flags);
855 
856     switch (event) {
857     case BTC_SM_ENTER_EVT:
858 
859         /* we are again in started state, clear any remote suspend flags */
860         btc_av_cb.flags &= ~BTC_AV_FLAG_REMOTE_SUSPEND;
861 
862         btc_report_audio_state(ESP_A2D_AUDIO_STATE_STARTED, &(btc_av_cb.peer_bda));
863 
864         /* increase the a2dp consumer task priority temporarily when start
865         ** audio playing, to avoid overflow the audio packet queue. */
866         // adjust_priority_a2dp(TRUE);
867 
868         break;
869 
870     case BTC_SM_EXIT_EVT:
871         /* restore the a2dp consumer task priority when stop audio playing. */
872         // adjust_priority_a2dp(FALSE);
873 
874         break;
875 
876     case BTC_AV_START_STREAM_REQ_EVT:
877 #if BTC_AV_SRC_INCLUDED
878         /* we were remotely started, just ack back the local request */
879         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
880             btc_a2dp_on_started(NULL, TRUE);
881         }
882 #endif /* BTC_AV_SRC_INCLUDED */
883         break;
884 
885     /* fixme -- use suspend = true always to work around issue with BTA AV */
886     case BTC_AV_STOP_STREAM_REQ_EVT:
887     case BTC_AV_SUSPEND_STREAM_REQ_EVT:
888 
889         /* set pending flag to ensure btc task is not trying to restart
890            stream while suspend is in progress */
891         btc_av_cb.flags |= BTC_AV_FLAG_LOCAL_SUSPEND_PENDING;
892 
893         /* if we were remotely suspended but suspend locally, local suspend
894            always overrides */
895         btc_av_cb.flags &= ~BTC_AV_FLAG_REMOTE_SUSPEND;
896 #if BTC_AV_SRC_INCLUDED
897         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
898             /* immediately stop transmission of frames while suspend is pending */
899             btc_a2dp_source_set_tx_flush(TRUE);
900         }
901 #endif /* BTC_AV_SRC_INCLUDED */
902 #if BTC_AV_SINK_INCLUDED
903         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
904             btc_a2dp_sink_set_rx_flush(TRUE);
905             btc_a2dp_on_stopped(NULL);
906         }
907 #endif /* BTC_AV_SINK_INCLUDED */
908         BTA_AvStop(TRUE);
909         break;
910 
911     case BTC_AV_DISCONNECT_REQ_EVT:
912 
913         /* request avdtp to close */
914         BTA_AvClose(btc_av_cb.bta_handle);
915         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) {
916             BTA_AvCloseRc(btc_av_cb.bta_handle);
917         }
918 
919         /* inform the application that we are disconnecting */
920         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTING, &(btc_av_cb.peer_bda), 0);
921 
922         /* wait in closing state until fully closed */
923         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_CLOSING);
924         break;
925 
926     case BTA_AV_SUSPEND_EVT:
927 
928         BTC_TRACE_DEBUG("BTA_AV_SUSPEND_EVT status %d, init %d\n",
929                  p_av->suspend.status, p_av->suspend.initiator);
930 
931         /* a2dp suspended, stop media task until resumed */
932         btc_a2dp_on_suspended(&p_av->suspend);
933 
934         /* if not successful, remain in current state */
935         if (p_av->suspend.status != BTA_AV_SUCCESS) {
936             btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING;
937 #if BTC_AV_SRC_INCLUDED
938             if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
939                 /* suspend failed, reset back tx flush state */
940                 btc_a2dp_source_set_tx_flush(FALSE);
941             }
942 #endif /* BTC_AV_SRC_INCLUDED */
943             return FALSE;
944         }
945 
946         if (p_av->suspend.initiator != TRUE) {
947             /* remote suspend, notify HAL and await audioflinger to
948                suspend/stop stream */
949 
950             /* set remote suspend flag to block media task from restarting
951                stream only if we did not already initiate a local suspend */
952             if ((btc_av_cb.flags & BTC_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0) {
953                 btc_av_cb.flags |= BTC_AV_FLAG_REMOTE_SUSPEND;
954             }
955 
956             btc_report_audio_state(ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND, &(btc_av_cb.peer_bda));
957         } else {
958             btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda));
959         }
960 
961         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED);
962 
963         /* suspend completed and state changed, clear pending status */
964         btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING;
965         break;
966 
967     case BTA_AV_STOP_EVT:
968 
969         btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP;
970         btc_a2dp_on_stopped(&p_av->suspend);
971 
972         btc_report_audio_state(ESP_A2D_AUDIO_STATE_STOPPED, &(btc_av_cb.peer_bda));
973 
974         /* if stop was successful, change state to open */
975         if (p_av->suspend.status == BTA_AV_SUCCESS) {
976             btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_OPENED);
977         }
978         break;
979 
980     case BTA_AV_CLOSE_EVT:
981         btc_av_cb.flags |= BTC_AV_FLAG_PENDING_STOP;
982 
983         /* avdtp link is closed */
984         btc_a2dp_on_stopped(NULL);
985         tBTA_AV_CLOSE *close = (tBTA_AV_CLOSE *)p_data;
986         /* inform the application that we are disconnected */
987         btc_report_connection_state(ESP_A2D_CONNECTION_STATE_DISCONNECTED, &(btc_av_cb.peer_bda),
988                                     close->disc_rsn);
989         btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
990 
991         if (g_a2dp_source_ongoing_deinit) {
992             clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
993         } else if (g_a2dp_sink_ongoing_deinit) {
994             clean_up(BTA_A2DP_SINK_SERVICE_ID);
995         }
996         break;
997 
998     CHECK_RC_EVENT(event, p_data);
999 
1000     case BTA_AV_SNK_PSC_CFG_EVT:
1001         break;
1002     case BTA_AV_SET_DELAY_VALUE_EVT:
1003 #if BTC_AV_SINK_INCLUDED
1004         param.a2d_set_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
1005         param.a2d_set_delay_value_stat.set_state = ((tBTA_AV *)p_data)->delay.status;
1006         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
1007 #endif /* BTC_AV_SINK_INCLUDED */
1008         break;
1009 
1010     case BTA_AV_GET_DELAY_VALUE_EVT:
1011 #if BTC_AV_SINK_INCLUDED
1012         param.a2d_get_delay_value_stat.delay_value = ((tBTA_AV *)p_data)->delay.delay_value;
1013         btc_a2d_cb_to_app(ESP_A2D_SNK_GET_DELAY_VALUE_EVT, &param);
1014 #endif /* BTC_AV_SINK_INCLUDED */
1015         break;
1016 
1017     default:
1018         BTC_TRACE_WARNING("%s : unhandled event:%s\n", __FUNCTION__,
1019                  dump_av_sm_event_name(event));
1020         return FALSE;
1021 
1022     }
1023     return TRUE;
1024 }
1025 
1026 /*****************************************************************************
1027 **  Local event handlers
1028 ******************************************************************************/
1029 
btc_av_event_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)1030 void btc_av_event_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
1031 {
1032     tBTA_AV *av_src = (tBTA_AV *)p_src;
1033     tBTA_AV *av_dest = (tBTA_AV *)p_dest;
1034 
1035     // First copy the structure
1036     memcpy(p_dest, p_src, sizeof(tBTA_AV));
1037 
1038     switch (msg->act) {
1039     case BTA_AV_META_MSG_EVT:
1040         if (av_src->meta_msg.p_data && av_src->meta_msg.len) {
1041             av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
1042             assert(av_dest->meta_msg.p_data);
1043             memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data, av_src->meta_msg.len);
1044         }
1045 
1046         if (av_src->meta_msg.p_msg) {
1047             av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
1048             assert(av_dest->meta_msg.p_msg);
1049             memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg, sizeof(tAVRC_MSG));
1050 
1051             if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
1052                     av_src->meta_msg.p_msg->vendor.vendor_len) {
1053                 av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
1054                             av_src->meta_msg.p_msg->vendor.vendor_len);
1055                 assert(av_dest->meta_msg.p_msg->vendor.p_vendor_data);
1056                 memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
1057                        av_src->meta_msg.p_msg->vendor.p_vendor_data,
1058                        av_src->meta_msg.p_msg->vendor.vendor_len);
1059             }
1060         }
1061         break;
1062 
1063     default:
1064         break;
1065     }
1066 }
1067 
btc_av_event_free_data(btc_msg_t * msg)1068 static void btc_av_event_free_data(btc_msg_t *msg)
1069 {
1070     switch (msg->act) {
1071     case BTA_AV_META_MSG_EVT: {
1072         tBTA_AV *av = (tBTA_AV *)msg->arg;
1073         if (av->meta_msg.p_data) {
1074             osi_free(av->meta_msg.p_data);
1075         }
1076 
1077         if (av->meta_msg.p_msg) {
1078             if (av->meta_msg.p_msg->vendor.p_vendor_data) {
1079                 osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
1080             }
1081             osi_free(av->meta_msg.p_msg);
1082         }
1083     }
1084     break;
1085 
1086     default:
1087         break;
1088     }
1089 }
1090 
1091 /*******************************************************************************
1092 **
1093 ** Function         btc_av_init
1094 **
1095 ** Description      Initializes btc AV if not already done
1096 **
1097 ** Returns          bt_status_t
1098 **
1099 *******************************************************************************/
btc_av_init(int service_id)1100 static bt_status_t btc_av_init(int service_id)
1101 {
1102 
1103 #if A2D_DYNAMIC_MEMORY == TRUE
1104     if (btc_av_cb_ptr != NULL) {
1105         return BT_STATUS_FAIL;
1106     }
1107 
1108     if ((btc_av_cb_ptr = (btc_av_cb_t *)osi_malloc(sizeof(btc_av_cb_t))) == NULL) {
1109         APPL_TRACE_ERROR("%s malloc failed!", __func__);
1110         return BT_STATUS_NOMEM;
1111     }
1112     memset((void *)btc_av_cb_ptr, 0, sizeof(btc_av_cb_t));
1113 #endif
1114 
1115     if (btc_av_cb.sm_handle == NULL) {
1116         btc_av_cb.service_id = service_id;
1117         bool stat = false;
1118         if (service_id == BTA_A2DP_SOURCE_SERVICE_ID) {
1119 #if BTC_AV_SRC_INCLUDED
1120             stat = btc_a2dp_source_startup();
1121 #endif
1122         } else if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
1123 #if BTC_AV_SINK_INCLUDED
1124             stat = btc_a2dp_sink_startup();
1125 #endif
1126         }
1127 
1128         if (!stat) {
1129 #if A2D_DYNAMIC_MEMORY == TRUE
1130             osi_free(btc_av_cb_ptr);
1131             btc_av_cb_ptr = NULL;
1132 #endif
1133             g_a2dp_on_init = false;
1134             g_a2dp_on_deinit = true;
1135             g_a2dp_source_ongoing_deinit = false;
1136             g_a2dp_sink_ongoing_deinit = false;
1137             goto av_init_fail;
1138         }
1139 
1140         /* Also initialize the AV state machine */
1141         btc_av_cb.sm_handle =
1142             btc_sm_init((const btc_sm_handler_t *)btc_av_state_handlers, BTC_AV_STATE_IDLE);
1143 
1144         if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
1145             btc_dm_enable_service(BTA_A2DP_SINK_SERVICE_ID);
1146         } else {
1147             btc_dm_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1148         }
1149 
1150         btc_a2dp_on_init();
1151         g_a2dp_on_init = true;
1152         g_a2dp_on_deinit = false;
1153         g_a2dp_source_ongoing_deinit = false;
1154         g_a2dp_sink_ongoing_deinit = false;
1155 
1156         esp_a2d_cb_param_t param;
1157         memset(&param, 0, sizeof(esp_a2d_cb_param_t));
1158         param.a2d_prof_stat.init_state = ESP_A2D_INIT_SUCCESS;
1159         btc_a2d_cb_to_app(ESP_A2D_PROF_STATE_EVT, &param);
1160         return BT_STATUS_SUCCESS;
1161     }
1162 
1163 av_init_fail:
1164     return BT_STATUS_FAIL;
1165 }
1166 
1167 /*******************************************************************************
1168 **
1169 ** Function         connect
1170 **
1171 ** Description      Establishes the AV signalling channel with the remote headset
1172 **
1173 ** Returns          bt_status_t
1174 **
1175 *******************************************************************************/
1176 
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)1177 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
1178 {
1179     btc_av_connect_req_t connect_req;
1180     memcpy(&connect_req.target_bda, bd_addr, sizeof(bt_bdaddr_t));
1181     connect_req.uuid = uuid;
1182     BTC_TRACE_DEBUG("%s\n", __FUNCTION__);
1183 
1184     btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_CONNECT_REQ_EVT, (char *)&connect_req);
1185 
1186     return BT_STATUS_SUCCESS;
1187 }
1188 
1189 /*******************************************************************************
1190 **
1191 ** Function         clean_up
1192 **
1193 ** Description      Shuts down the AV interface and does the cleanup
1194 **
1195 ** Returns          None
1196 **
1197 *******************************************************************************/
clean_up(int service_id)1198 static void clean_up(int service_id)
1199 {
1200     BTC_TRACE_DEBUG("%s\n", __FUNCTION__);
1201 
1202     if (service_id == BTA_A2DP_SOURCE_SERVICE_ID) {
1203 #if BTC_AV_SRC_INCLUDED
1204         btc_a2dp_source_shutdown();
1205         if (btc_av_cb.tle_av_open_on_rc) {
1206             osi_alarm_free(btc_av_cb.tle_av_open_on_rc);
1207             btc_av_cb.tle_av_open_on_rc = NULL;
1208         }
1209 #endif /* BTC_AV_SRC_INCLUDED */
1210         btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
1211     }
1212 
1213     if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
1214 #if BTC_AV_SINK_INCLUDED
1215         btc_a2dp_sink_shutdown();
1216 #endif /* BTC_AV_SINK_INCLUDED */
1217         btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID);
1218     }
1219 
1220     /* Also shut down the AV state machine */
1221     btc_sm_shutdown(btc_av_cb.sm_handle);
1222     btc_av_cb.sm_handle = NULL;
1223 
1224 #if A2D_DYNAMIC_MEMORY == TRUE
1225     osi_free(btc_av_cb_ptr);
1226     btc_av_cb_ptr = NULL;
1227 #endif
1228     g_a2dp_on_init = false;
1229     g_a2dp_on_deinit = true;
1230     g_a2dp_source_ongoing_deinit = false;
1231     g_a2dp_sink_ongoing_deinit = false;
1232 
1233     esp_a2d_cb_param_t param;
1234     memset(&param, 0, sizeof(esp_a2d_cb_param_t));
1235     param.a2d_prof_stat.init_state = ESP_A2D_DEINIT_SUCCESS;
1236     btc_a2d_cb_to_app(ESP_A2D_PROF_STATE_EVT, &param);
1237 }
1238 
1239 /*******************************************************************************
1240 **
1241 ** Function         btc_av_get_sm_handle
1242 **
1243 ** Description      Fetches current av SM handle
1244 **
1245 ** Returns          None
1246 **
1247 *******************************************************************************/
1248 
btc_av_get_sm_handle(void)1249 btc_sm_handle_t btc_av_get_sm_handle(void)
1250 {
1251     return btc_av_cb.sm_handle;
1252 }
1253 
1254 /*******************************************************************************
1255 **
1256 ** Function         btc_av_stream_ready
1257 **
1258 ** Description      Checks whether AV is ready for starting a stream
1259 **
1260 ** Returns          None
1261 **
1262 *******************************************************************************/
1263 
btc_av_stream_ready(void)1264 BOOLEAN btc_av_stream_ready(void)
1265 {
1266     btc_sm_state_t state = btc_sm_get_state(btc_av_cb.sm_handle);
1267 
1268     BTC_TRACE_DEBUG("btc_av_stream_ready : sm hdl %d, state %d, flags %x\n",
1269               (int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
1270 
1271     /* check if we are remotely suspended or stop is pending */
1272     if (btc_av_cb.flags & (BTC_AV_FLAG_REMOTE_SUSPEND | BTC_AV_FLAG_PENDING_STOP)) {
1273         return FALSE;
1274     }
1275 
1276     return (state == BTC_AV_STATE_OPENED);
1277 }
1278 
1279 /*******************************************************************************
1280 **
1281 ** Function         btc_av_stream_started_ready
1282 **
1283 ** Description      Checks whether AV ready for media start in streaming state
1284 **
1285 ** Returns          None
1286 **
1287 *******************************************************************************/
1288 
btc_av_stream_started_ready(void)1289 BOOLEAN btc_av_stream_started_ready(void)
1290 {
1291     btc_sm_state_t state = btc_sm_get_state(btc_av_cb.sm_handle);
1292 
1293     BTC_TRACE_DEBUG("btc_av_stream_started : sm hdl %d, state %d, flags %x\n",
1294               (int)btc_av_cb.sm_handle, state, btc_av_cb.flags);
1295 
1296     /* disallow media task to start if we have pending actions */
1297     if (btc_av_cb.flags & (BTC_AV_FLAG_LOCAL_SUSPEND_PENDING | BTC_AV_FLAG_REMOTE_SUSPEND
1298                            | BTC_AV_FLAG_PENDING_STOP)) {
1299         return FALSE;
1300     }
1301 
1302     return (state == BTC_AV_STATE_STARTED);
1303 }
1304 
1305 /*******************************************************************************
1306 **
1307 ** Function         btc_dispatch_sm_event
1308 **
1309 ** Description      Send event to AV statemachine
1310 **
1311 ** Returns          None
1312 **
1313 *******************************************************************************/
1314 
1315 /* used to pass events to AV statemachine from other tasks */
btc_dispatch_sm_event(btc_av_sm_event_t event,void * p_data,int len)1316 void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len)
1317 {
1318     btc_msg_t msg;
1319     msg.sig = BTC_SIG_API_CALL;
1320     msg.pid = BTC_PID_A2DP;
1321     msg.act = event;
1322     btc_transfer_context(&msg, p_data, len, NULL, NULL);
1323 }
1324 
bte_av_callback(tBTA_AV_EVT event,tBTA_AV * p_data)1325 static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
1326 {
1327     bt_status_t stat;
1328     btc_msg_t msg;
1329 
1330     msg.sig = BTC_SIG_API_CB;
1331     msg.pid = BTC_PID_A2DP;
1332     msg.act = (uint8_t) event;
1333     stat = btc_transfer_context(&msg, p_data, sizeof(tBTA_AV),
1334                                     btc_av_event_deep_copy, btc_av_event_free_data);
1335 
1336     if (stat) {
1337         BTC_TRACE_ERROR("%s transfer failed\n", __func__);
1338     }
1339 }
1340 
1341 #if BTC_AV_SINK_INCLUDED
bte_av_media_callback(tBTA_AV_EVT event,tBTA_AV_MEDIA * p_data)1342 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
1343 {
1344     btc_sm_state_t state;
1345     UINT8 que_len;
1346     tA2D_STATUS a2d_status;
1347     tA2D_SBC_CIE sbc_cie;
1348 
1349     if (event == BTA_AV_MEDIA_DATA_EVT) { /* Switch to BTC_MEDIA context */
1350         state = btc_sm_get_state(btc_av_cb.sm_handle);
1351         if ( (state == BTC_AV_STATE_STARTED) || /* send SBC packets only in Started State */
1352                 (state == BTC_AV_STATE_OPENED) ) {
1353             que_len = btc_a2dp_sink_enque_buf((BT_HDR *)p_data);
1354             BTC_TRACE_DEBUG(" Packets in Que %d\n", que_len);
1355         } else {
1356             return;
1357         }
1358     }
1359 
1360     if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
1361         /* send a command to BT Media Task */
1362         btc_a2dp_sink_reset_decoder((UINT8 *)p_data);
1363 
1364         /* currently only supportes SBC */
1365         a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
1366         if (a2d_status == A2D_SUCCESS) {
1367             btc_msg_t msg;
1368             btc_av_args_t arg;
1369 
1370             msg.sig = BTC_SIG_API_CB;
1371             msg.pid = BTC_PID_A2DP;
1372             msg.act = BTC_AV_SINK_CONFIG_REQ_EVT;
1373 
1374             memset(&arg, 0, sizeof(btc_av_args_t));
1375             arg.mcc.type = ESP_A2D_MCT_SBC;
1376             memcpy(arg.mcc.cie.sbc, (uint8_t *)p_data + 3, ESP_A2D_CIE_LEN_SBC);
1377             btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
1378         } else {
1379             BTC_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
1380         }
1381     }
1382     UNUSED(que_len);
1383 }
1384 #else
bte_av_media_callback(tBTA_AV_EVT event,tBTA_AV_MEDIA * p_data)1385 static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
1386 {
1387     UNUSED(event);
1388     UNUSED(p_data);
1389     BTC_TRACE_WARNING("%s : event %u\n", __func__, event);
1390 }
1391 #endif
1392 
1393 /*******************************************************************************
1394 **
1395 ** Function         btc_av_execute_service
1396 **
1397 ** Description      Initializes/Shuts down the service
1398 **
1399 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1400 **
1401 *******************************************************************************/
btc_av_execute_service(BOOLEAN b_enable,UINT8 tsep)1402 bt_status_t btc_av_execute_service(BOOLEAN b_enable, UINT8 tsep)
1403 {
1404     if (b_enable) {
1405         /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
1406          * handle this request in order to allow incoming connections to succeed.
1407          * We need to put this back once support for this is added */
1408 
1409         /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
1410          * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
1411          * be initiated by the app/audioflinger layers */
1412         if (g_av_with_rc) {
1413             BTC_TRACE_WARNING("A2DP Enable with AVRC")
1414             BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD |
1415                         BTA_AV_FEAT_RCTG | BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
1416                         BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_DELAY_RPT,
1417                         bte_av_callback);
1418             BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, &bta_avrc_cos, tsep);
1419         } else {
1420             BTC_TRACE_WARNING("A2DP Enable without AVRC")
1421             BTA_AvEnable(BTA_SEC_AUTHENTICATE, BTA_AV_FEAT_NO_SCO_SSPD | BTA_AV_FEAT_DELAY_RPT, bte_av_callback);
1422             BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTC_AV_SERVICE_NAME, 0, bte_av_media_callback, &bta_av_a2d_cos, NULL, tsep);
1423         }
1424     } else {
1425         BTA_AvDeregister(btc_av_cb.bta_handle);
1426         BTA_AvDisable();
1427     }
1428     return BT_STATUS_SUCCESS;
1429 }
1430 
1431 /*******************************************************************************
1432 **
1433 ** Function         btc_av_source_execute_service
1434 **
1435 ** Description      Initializes/Shuts down the A2DP source service
1436 **
1437 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1438 **
1439 *******************************************************************************/
btc_av_source_execute_service(BOOLEAN b_enable)1440 bt_status_t btc_av_source_execute_service(BOOLEAN b_enable)
1441 {
1442     return btc_av_execute_service(b_enable, AVDT_TSEP_SRC);
1443 }
1444 
1445 /*******************************************************************************
1446 **
1447 ** Function         btc_av_sink_execute_service
1448 **
1449 ** Description      Initializes/Shuts down the service
1450 **
1451 ** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1452 **
1453 *******************************************************************************/
btc_av_sink_execute_service(BOOLEAN b_enable)1454 bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable)
1455 {
1456     bt_status_t ret = btc_av_execute_service(b_enable, AVDT_TSEP_SNK);
1457     if (ret != BT_STATUS_SUCCESS) {
1458         return ret;
1459     }
1460 #if (BTA_AV_SINK_INCLUDED == TRUE)
1461     BTA_AvEnable_Sink(b_enable);
1462 #endif
1463     return BT_STATUS_SUCCESS;
1464 }
1465 
1466 /*******************************************************************************
1467 **
1468 ** Function         btc_av_is_connected
1469 **
1470 ** Description      Checks if av has a connected sink
1471 **
1472 ** Returns          BOOLEAN
1473 **
1474 *******************************************************************************/
btc_av_is_connected(void)1475 BOOLEAN btc_av_is_connected(void)
1476 {
1477     btc_sm_state_t state = btc_sm_get_state(btc_av_cb.sm_handle);
1478     return ((state == BTC_AV_STATE_OPENED) || (state ==  BTC_AV_STATE_STARTED));
1479 }
1480 
1481 /*******************************************************************************
1482  *
1483  * Function         btc_av_get_service_id
1484  *
1485  * Description      Get the current AV service ID.
1486  *
1487  * Returns          The stream endpoint type: either BTA_A2DP_SOURCE_SERVICE_ID or
1488  *                  BTA_A2DP_SINK_SERVICE_ID.
1489  *
1490  ******************************************************************************/
btc_av_get_service_id(void)1491 uint8_t btc_av_get_service_id(void)
1492 {
1493     return btc_av_cb.service_id;
1494 }
1495 
1496 /*******************************************************************************
1497  *
1498  * Function         btc_av_get_peer_sep
1499  *
1500  * Description      Get the stream endpoint type.
1501  *
1502  * Returns          The stream endpoint type: either AVDT_TSEP_SRC or
1503  *                  AVDT_TSEP_SNK.
1504  *
1505  ******************************************************************************/
1506 
btc_av_get_peer_sep(void)1507 uint8_t btc_av_get_peer_sep(void)
1508 {
1509     return btc_av_cb.peer_sep;
1510 }
1511 /*******************************************************************************
1512 **
1513 ** Function         btc_av_is_peer_edr
1514 **
1515 ** Description      Check if the connected a2dp device supports
1516 **                  EDR or not. Only when connected this function
1517 **                  will accurately provide a true capability of
1518 **                  remote peer. If not connected it will always be false.
1519 **
1520 ** Returns          TRUE if remote device is capable of EDR
1521 **
1522 *******************************************************************************/
btc_av_is_peer_edr(void)1523 BOOLEAN btc_av_is_peer_edr(void)
1524 {
1525     BTC_ASSERTC(btc_av_is_connected(), "No active a2dp connection\n", 0);
1526 
1527     if (btc_av_cb.edr) {
1528         return TRUE;
1529     } else {
1530         return FALSE;
1531     }
1532 }
1533 
1534 /******************************************************************************
1535 **
1536 ** Function        btc_av_clear_remote_suspend_flag
1537 **
1538 ** Description     Clears btc_av_cb.flags if BTC_AV_FLAG_REMOTE_SUSPEND is set
1539 **
1540 ** Returns          void
1541 ******************************************************************************/
btc_av_clear_remote_suspend_flag(void)1542 void btc_av_clear_remote_suspend_flag(void)
1543 {
1544     BTC_TRACE_DEBUG("%s: flag :%x\n", __func__, btc_av_cb.flags);
1545     btc_av_cb.flags &= ~BTC_AV_FLAG_REMOTE_SUSPEND;
1546 }
1547 
btc_a2dp_call_handler(btc_msg_t * msg)1548 void btc_a2dp_call_handler(btc_msg_t *msg)
1549 {
1550     btc_av_args_t *arg = (btc_av_args_t *)(msg->arg);
1551     switch (msg->act) {
1552 #if BTC_AV_SINK_INCLUDED
1553     case BTC_AV_SINK_CONFIG_REQ_EVT: {
1554         btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
1555         break;
1556     }
1557     case BTC_AV_SINK_API_INIT_EVT: {
1558         btc_a2d_sink_init();
1559         // todo: callback to application
1560         break;
1561     }
1562     case BTC_AV_SINK_API_DEINIT_EVT: {
1563         btc_a2d_sink_deinit();
1564         // todo: callback to application
1565         break;
1566     }
1567     case BTC_AV_SINK_API_CONNECT_EVT: {
1568         btc_a2d_sink_connect(&arg->connect);
1569         // todo: callback to application
1570         break;
1571     }
1572     case BTC_AV_SINK_API_DISCONNECT_EVT: {
1573         CHECK_BTAV_INIT();
1574         btc_av_disconn_req_t disconn_req;
1575         memcpy(&disconn_req.target_bda, &arg->disconn, sizeof(bt_bdaddr_t));
1576         btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req);
1577         break;
1578     }
1579     case BTC_AV_SINK_API_REG_DATA_CB_EVT: {
1580         btc_a2dp_sink_reg_data_cb(arg->data_cb);
1581         break;
1582     }
1583     case BTC_AV_SINK_API_SET_DELAY_VALUE_EVT: {
1584         btc_a2d_sink_set_delay_value(arg->delay_value);
1585         break;
1586     }
1587     case BTC_AV_SINK_API_GET_DELAY_VALUE_EVT: {
1588         btc_a2d_sink_get_delay_value();
1589         break;
1590     }
1591 #endif /* BTC_AV_SINK_INCLUDED */
1592 #if BTC_AV_SRC_INCLUDED
1593     case BTC_AV_SRC_API_INIT_EVT: {
1594         btc_a2d_src_init();
1595         break;
1596     }
1597     case BTC_AV_SRC_API_DEINIT_EVT: {
1598         btc_a2d_src_deinit();
1599         break;
1600     }
1601     case BTC_AV_SRC_API_CONNECT_EVT: {
1602         btc_a2d_src_connect(&arg->src_connect);
1603         break;
1604     }
1605     case BTC_AV_SRC_API_DISCONNECT_EVT: {
1606         CHECK_BTAV_INIT();
1607         btc_av_disconn_req_t disconn_req;
1608         memcpy(&disconn_req.target_bda, &arg->src_disconn, sizeof(bt_bdaddr_t));
1609         btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, &disconn_req);
1610         break;
1611     }
1612     case BTC_AV_SRC_API_REG_DATA_CB_EVT: {
1613         btc_a2dp_src_reg_data_cb(arg->src_data_cb);
1614         break;
1615     }
1616 #endif /* BTC_AV_SRC_INCLUDED */
1617     case BTC_AV_API_MEDIA_CTRL_EVT: {
1618         btc_a2dp_control_media_ctrl(arg->ctrl);
1619         break;
1620     }
1621     case BTC_AV_CONNECT_REQ_EVT:
1622         btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (char *)msg->arg);
1623         break;
1624     // case BTC_AV_DISCONNECT_REQ_EVT:
1625     case BTC_AV_START_STREAM_REQ_EVT:
1626     case BTC_AV_STOP_STREAM_REQ_EVT:
1627     case BTC_AV_SUSPEND_STREAM_REQ_EVT: {
1628         btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, NULL);
1629         break;
1630     }
1631     default:
1632         BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
1633     }
1634 }
1635 
btc_a2dp_cb_handler(btc_msg_t * msg)1636 void btc_a2dp_cb_handler(btc_msg_t *msg)
1637 {
1638     btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
1639     btc_av_event_free_data(msg);
1640 }
1641 
1642 #if BTC_AV_SINK_INCLUDED
1643 
1644 /*******************************************************************************
1645 **
1646 ** Function         init_sink
1647 **
1648 ** Description      Initializes the AV interface for sink mode
1649 **
1650 ** Returns          bt_status_t
1651 **
1652 *******************************************************************************/
btc_a2d_sink_init(void)1653 static bt_status_t btc_a2d_sink_init(void)
1654 {
1655     BTC_TRACE_DEBUG("%s()\n", __func__);
1656 
1657     return btc_av_init(BTA_A2DP_SINK_SERVICE_ID);
1658 }
1659 
btc_a2d_sink_connect(bt_bdaddr_t * remote_bda)1660 static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda)
1661 {
1662     BTC_TRACE_DEBUG("%s\n", __FUNCTION__);
1663     CHECK_BTAV_INIT();
1664 
1665     return btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, remote_bda, connect_int);
1666 }
1667 
btc_a2d_sink_set_delay_value(UINT16 delay_value)1668 static void btc_a2d_sink_set_delay_value(UINT16 delay_value)
1669 {
1670     esp_a2d_cb_param_t param;
1671 
1672     if (delay_value <= BTC_DELAY_REPORT_DFT_VALUE) {
1673         param.a2d_set_delay_value_stat.delay_value = 0;
1674         param.a2d_set_delay_value_stat.set_state = ESP_A2D_SET_INVALID_PARAMS;
1675         btc_a2d_cb_to_app(ESP_A2D_SNK_SET_DELAY_VALUE_EVT, &param);
1676     } else {
1677         BTA_SetDelayValue(delay_value);
1678     }
1679 }
1680 
btc_a2d_sink_get_delay_value(void)1681 static void btc_a2d_sink_get_delay_value(void)
1682 {
1683     BTA_GetDelayValue();
1684 }
1685 
btc_a2d_sink_deinit(void)1686 static void btc_a2d_sink_deinit(void)
1687 {
1688     g_a2dp_sink_ongoing_deinit = true;
1689     if (btc_av_is_connected()) {
1690         BTA_AvClose(btc_av_cb.bta_handle);
1691         if (btc_av_cb.peer_sep == AVDT_TSEP_SRC && g_av_with_rc == true) {
1692             BTA_AvCloseRc(btc_av_cb.bta_handle);
1693         }
1694     } else {
1695         clean_up(BTA_A2DP_SINK_SERVICE_ID);
1696     }
1697 }
1698 
1699 #endif /* BTC_AV_SINK_INCLUDED */
1700 
1701 #if BTC_AV_SRC_INCLUDED
1702 
1703 /*******************************************************************************
1704 **
1705 ** Function         btc_a2d_src_init
1706 **
1707 ** Description      Initializes the AV interface for source mode
1708 **
1709 ** Returns          bt_status_t
1710 **
1711 *******************************************************************************/
btc_a2d_src_init(void)1712 static bt_status_t btc_a2d_src_init(void)
1713 {
1714     BTC_TRACE_DEBUG("%s()\n", __func__);
1715 
1716     return btc_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
1717 }
1718 
btc_a2d_src_deinit(void)1719 static void btc_a2d_src_deinit(void)
1720 {
1721     g_a2dp_source_ongoing_deinit = true;
1722     if (btc_av_is_connected()) {
1723         BTA_AvClose(btc_av_cb.bta_handle);
1724         if (btc_av_cb.peer_sep == AVDT_TSEP_SNK && g_av_with_rc == true) {
1725             BTA_AvCloseRc(btc_av_cb.bta_handle);
1726         }
1727     } else {
1728         clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
1729     }
1730 }
1731 
btc_a2d_src_connect(bt_bdaddr_t * remote_bda)1732 static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda)
1733 {
1734     BTC_TRACE_DEBUG("%s\n", __FUNCTION__);
1735     CHECK_BTAV_INIT();
1736 
1737     return btc_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, remote_bda, connect_int);
1738 }
1739 
1740 #endif /* BTC_AV_SRC_INCLUDED */
1741 
1742 #endif /* #if BTC_AV_INCLUDED */
1743