1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "common/bt_target.h"
8 #include <string.h>
9 #include "esp_err.h"
10 #include "esp_a2dp_api.h"
11 #include "esp_bt_main.h"
12 #include "btc/btc_manage.h"
13 #include "btc_av.h"
14 
15 #if BTC_AV_INCLUDED
16 
17 #if BTC_AV_SINK_INCLUDED
esp_a2d_sink_init(void)18 esp_err_t esp_a2d_sink_init(void)
19 {
20     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
21         return ESP_ERR_INVALID_STATE;
22     }
23 
24     if (g_a2dp_on_init || g_a2dp_sink_ongoing_deinit) {
25         return ESP_ERR_INVALID_STATE;
26     }
27 
28     btc_msg_t msg;
29 
30     msg.sig = BTC_SIG_API_CALL;
31     msg.pid = BTC_PID_A2DP;
32     msg.act = BTC_AV_SINK_API_INIT_EVT;
33 
34     /* Switch to BTC context */
35     bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
36     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
37 }
38 
esp_a2d_sink_deinit(void)39 esp_err_t esp_a2d_sink_deinit(void)
40 {
41     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
42         return ESP_ERR_INVALID_STATE;
43     }
44 
45     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
46         return ESP_ERR_INVALID_STATE;
47     }
48 
49     btc_msg_t msg;
50 
51     msg.sig = BTC_SIG_API_CALL;
52     msg.pid = BTC_PID_A2DP;
53     msg.act = BTC_AV_SINK_API_DEINIT_EVT;
54 
55     /* Switch to BTC context */
56     bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
57     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
58 }
59 
esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)60 esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
61 {
62     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
63         return ESP_ERR_INVALID_STATE;
64     }
65 
66     if (g_a2dp_sink_ongoing_deinit) {
67         return ESP_ERR_INVALID_STATE;
68     }
69 
70     btc_msg_t msg;
71     msg.sig = BTC_SIG_API_CALL;
72     msg.pid = BTC_PID_A2DP;
73     msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;
74 
75     btc_av_args_t arg;
76     memset(&arg, 0, sizeof(btc_av_args_t));
77     arg.data_cb = callback;
78 
79     /* Switch to BTC context */
80     bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
81     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
82 }
83 
esp_a2d_sink_connect(esp_bd_addr_t remote_bda)84 esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
85 {
86     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
87         return ESP_ERR_INVALID_STATE;
88     }
89 
90     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
91         return ESP_ERR_INVALID_STATE;
92     }
93 
94     bt_status_t stat;
95     btc_av_args_t arg;
96     btc_msg_t msg;
97 
98     msg.sig = BTC_SIG_API_CALL;
99     msg.pid = BTC_PID_A2DP;
100     msg.act = BTC_AV_SINK_API_CONNECT_EVT;
101 
102     memset(&arg, 0, sizeof(btc_av_args_t));
103 
104     /* Switch to BTC context */
105     memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
106     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
107     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
108 }
109 
esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)110 esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
111 {
112     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
113         return ESP_ERR_INVALID_STATE;
114     }
115 
116     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
117         return ESP_ERR_INVALID_STATE;
118     }
119 
120     bt_status_t stat;
121     btc_av_args_t arg;
122     btc_msg_t msg;
123 
124     msg.sig = BTC_SIG_API_CALL;
125     msg.pid = BTC_PID_A2DP;
126     msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;
127 
128     /* Switch to BTC context */
129     memcpy(&(arg.disconn), remote_bda, sizeof(bt_bdaddr_t));
130     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
131     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
132 }
133 
esp_a2d_sink_set_delay_value(uint16_t delay_value)134 esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value)
135 {
136     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
137         return ESP_ERR_INVALID_STATE;
138     }
139 
140     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
141         return ESP_ERR_INVALID_STATE;
142     }
143 
144     bt_status_t stat;
145     btc_av_args_t arg;
146     btc_msg_t msg;
147 
148     msg.sig = BTC_SIG_API_CALL;
149     msg.pid = BTC_PID_A2DP;
150     msg.act = BTC_AV_SINK_API_SET_DELAY_VALUE_EVT;
151 
152     memset(&arg, 0, sizeof(btc_av_args_t));
153     arg.delay_value = delay_value;
154 
155     /* Switch to BTC context */
156     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
157     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
158 }
159 
esp_a2d_sink_get_delay_value(void)160 esp_err_t esp_a2d_sink_get_delay_value(void)
161 {
162     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
163         return ESP_ERR_INVALID_STATE;
164     }
165 
166     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit) {
167         return ESP_ERR_INVALID_STATE;
168     }
169 
170     bt_status_t stat;
171     btc_msg_t msg;
172 
173     msg.sig = BTC_SIG_API_CALL;
174     msg.pid = BTC_PID_A2DP;
175     msg.act = BTC_AV_SINK_API_GET_DELAY_VALUE_EVT;
176 
177     /* Switch to BTC context */
178     stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
179     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
180 }
181 #endif /* BTC_AV_SINK_INCLUDED */
182 
esp_a2d_register_callback(esp_a2d_cb_t callback)183 esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
184 {
185     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
186         return ESP_ERR_INVALID_STATE;
187     }
188 
189     if (g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) {
190         return ESP_ERR_INVALID_STATE;
191     }
192 
193     if (callback == NULL) {
194         return ESP_FAIL;
195     }
196 
197     btc_profile_cb_set(BTC_PID_A2DP, callback);
198     return ESP_OK;
199 }
200 
esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)201 esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
202 {
203     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
204         return ESP_ERR_INVALID_STATE;
205     }
206 
207     if (g_a2dp_on_deinit || g_a2dp_sink_ongoing_deinit || g_a2dp_source_ongoing_deinit) {
208         return ESP_ERR_INVALID_STATE;
209     }
210 
211     bt_status_t stat;
212     btc_av_args_t arg;
213     btc_msg_t msg;
214 
215     msg.sig = BTC_SIG_API_CALL;
216     msg.pid = BTC_PID_A2DP;
217     msg.act = BTC_AV_API_MEDIA_CTRL_EVT;
218 
219     memset(&arg, 0, sizeof(btc_av_args_t));
220 
221     /* Switch to BTC context */
222     arg.ctrl = ctrl;
223     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
224     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
225 }
226 
227 #if BTC_AV_SRC_INCLUDED
esp_a2d_source_init(void)228 esp_err_t esp_a2d_source_init(void)
229 {
230     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
231         return ESP_ERR_INVALID_STATE;
232     }
233 
234     if (g_a2dp_on_init || g_a2dp_source_ongoing_deinit) {
235         return ESP_ERR_INVALID_STATE;
236     }
237 
238     btc_msg_t msg;
239 
240     msg.sig = BTC_SIG_API_CALL;
241     msg.pid = BTC_PID_A2DP;
242     msg.act = BTC_AV_SRC_API_INIT_EVT;
243 
244     /* Switch to BTC context */
245     bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
246     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
247 }
248 
esp_a2d_source_deinit(void)249 esp_err_t esp_a2d_source_deinit(void)
250 {
251     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
252         return ESP_ERR_INVALID_STATE;
253     }
254 
255     if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) {
256         return ESP_ERR_INVALID_STATE;
257     }
258 
259     btc_msg_t msg;
260 
261     msg.sig = BTC_SIG_API_CALL;
262     msg.pid = BTC_PID_A2DP;
263     msg.act = BTC_AV_SRC_API_DEINIT_EVT;
264 
265     /* Switch to BTC context */
266     bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
267     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
268 }
269 
esp_a2d_source_connect(esp_bd_addr_t remote_bda)270 esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda)
271 {
272     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
273         return ESP_ERR_INVALID_STATE;
274     }
275 
276     if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) {
277         return ESP_ERR_INVALID_STATE;
278     }
279 
280     bt_status_t stat;
281     btc_av_args_t arg;
282     btc_msg_t msg;
283 
284     msg.sig = BTC_SIG_API_CALL;
285     msg.pid = BTC_PID_A2DP;
286     msg.act = BTC_AV_SRC_API_CONNECT_EVT;
287 
288     memset(&arg, 0, sizeof(btc_av_args_t));
289 
290     /* Switch to BTC context */
291     memcpy(&(arg.src_connect), remote_bda, sizeof(bt_bdaddr_t));
292     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
293     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
294 }
295 
esp_a2d_source_disconnect(esp_bd_addr_t remote_bda)296 esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda)
297 {
298     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
299         return ESP_ERR_INVALID_STATE;
300     }
301 
302     if (g_a2dp_on_deinit || g_a2dp_source_ongoing_deinit) {
303         return ESP_ERR_INVALID_STATE;
304     }
305 
306     bt_status_t stat;
307     btc_av_args_t arg;
308     btc_msg_t msg;
309 
310     msg.sig = BTC_SIG_API_CALL;
311     msg.pid = BTC_PID_A2DP;
312     msg.act = BTC_AV_SRC_API_DISCONNECT_EVT;
313 
314     memset(&arg, 0, sizeof(btc_av_args_t));
315 
316     /* Switch to BTC context */
317     memcpy(&(arg.src_disconn), remote_bda, sizeof(bt_bdaddr_t));
318     stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
319     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
320 }
321 
esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback)322 esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback)
323 {
324     if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
325         return ESP_ERR_INVALID_STATE;
326     }
327 
328     if (g_a2dp_source_ongoing_deinit) {
329         return ESP_ERR_INVALID_STATE;
330     }
331 
332     btc_msg_t msg;
333     msg.sig = BTC_SIG_API_CALL;
334     msg.pid = BTC_PID_A2DP;
335     msg.act = BTC_AV_SRC_API_REG_DATA_CB_EVT;
336 
337     btc_av_args_t arg;
338     memset(&arg, 0, sizeof(btc_av_args_t));
339     arg.src_data_cb = callback;
340 
341     /* Switch to BTC context */
342     bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL, NULL);
343     return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
344 }
345 
346 #endif /* BTC_AV_SRC_INCLUDED */
347 
348 #endif /* #if BTC_AV_INCLUDED */
349