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