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