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