1 // Copyright 2018 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_hf_client_api.h"
19 #include "esp_bt_main.h"
20 #include "btc/btc_manage.h"
21 #include "btc_hf_client.h"
22 #include "bta/bta_api.h"
23 #include "bta/bta_hf_client_api.h"
24
25 #if BTC_HF_CLIENT_INCLUDED
esp_hf_client_register_callback(esp_hf_client_cb_t callback)26 esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback)
27 {
28 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
29 return ESP_ERR_INVALID_STATE;
30 }
31
32 if (callback == NULL) {
33 return ESP_FAIL;
34 }
35
36 btc_profile_cb_set(BTC_PID_HF_CLIENT, callback);
37 return ESP_OK;
38 }
39
esp_hf_client_init(void)40 esp_err_t esp_hf_client_init(void)
41 {
42 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
43 return ESP_ERR_INVALID_STATE;
44 }
45
46 btc_msg_t msg;
47
48 msg.sig = BTC_SIG_API_CALL;
49 msg.pid = BTC_PID_HF_CLIENT;
50 msg.act = BTC_HF_CLIENT_INIT_EVT;
51
52 /* Switch to BTC context */
53 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
54 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
55 }
56
esp_hf_client_deinit(void)57 esp_err_t esp_hf_client_deinit(void)
58 {
59 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
60 return ESP_ERR_INVALID_STATE;
61 }
62
63 btc_msg_t msg;
64
65 msg.sig = BTC_SIG_API_CALL;
66 msg.pid = BTC_PID_HF_CLIENT;
67 msg.act = BTC_HF_CLIENT_DEINIT_EVT;
68
69 /* Switch to BTC context */
70 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
71 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
72 }
73
esp_hf_client_connect(esp_bd_addr_t remote_bda)74 esp_err_t esp_hf_client_connect(esp_bd_addr_t remote_bda)
75 {
76 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
77 return ESP_ERR_INVALID_STATE;
78 }
79
80 bt_status_t stat;
81 btc_hf_client_args_t arg;
82 btc_msg_t msg;
83
84 msg.sig = BTC_SIG_API_CALL;
85 msg.pid = BTC_PID_HF_CLIENT;
86 msg.act = BTC_HF_CLIENT_CONNECT_EVT;
87
88 memset(&arg, 0, sizeof(btc_hf_client_args_t));
89
90 /* Switch to BTC context */
91 memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
92 stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
93 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
94 }
95
esp_hf_client_disconnect(esp_bd_addr_t remote_bda)96 esp_err_t esp_hf_client_disconnect(esp_bd_addr_t remote_bda)
97 {
98 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
99 return ESP_ERR_INVALID_STATE;
100 }
101
102 bt_status_t stat;
103 btc_hf_client_args_t arg;
104 btc_msg_t msg;
105
106 msg.sig = BTC_SIG_API_CALL;
107 msg.pid = BTC_PID_HF_CLIENT;
108 msg.act = BTC_HF_CLIENT_DISCONNECT_EVT;
109
110 memset(&arg, 0, sizeof(btc_hf_client_args_t));
111
112 /* Switch to BTC context */
113 memcpy(&(arg.disconnect), remote_bda, sizeof(bt_bdaddr_t));
114 stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
115 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
116 }
117
esp_hf_client_connect_audio(esp_bd_addr_t remote_bda)118 esp_err_t esp_hf_client_connect_audio(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 bt_status_t stat;
125 btc_hf_client_args_t arg;
126 btc_msg_t msg;
127
128 msg.sig = BTC_SIG_API_CALL;
129 msg.pid = BTC_PID_HF_CLIENT;
130 msg.act = BTC_HF_CLIENT_CONNECT_AUDIO_EVT;
131
132 memset(&arg, 0, sizeof(btc_hf_client_args_t));
133
134 /* Switch to BTC context */
135 memcpy(&(arg.connect_audio), remote_bda, sizeof(bt_bdaddr_t));
136 stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
137 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
138 }
139
esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda)140 esp_err_t esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda)
141 {
142 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
143 return ESP_ERR_INVALID_STATE;
144 }
145
146 bt_status_t stat;
147 btc_hf_client_args_t arg;
148 btc_msg_t msg;
149
150 msg.sig = BTC_SIG_API_CALL;
151 msg.pid = BTC_PID_HF_CLIENT;
152 msg.act = BTC_HF_CLIENT_DISCONNECT_AUDIO_EVT;
153
154 memset(&arg, 0, sizeof(btc_hf_client_args_t));
155
156 /* Switch to BTC context */
157 memcpy(&(arg.disconnect_audio), remote_bda, sizeof(bt_bdaddr_t));
158 stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
159 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
160 }
161
162
esp_hf_client_start_voice_recognition(void)163 esp_err_t esp_hf_client_start_voice_recognition(void)
164 {
165 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
166 return ESP_ERR_INVALID_STATE;
167 }
168
169 btc_msg_t msg;
170
171 msg.sig = BTC_SIG_API_CALL;
172 msg.pid = BTC_PID_HF_CLIENT;
173 msg.act = BTC_HF_CLIENT_START_VOICE_RECOGNITION_EVT;
174
175 /* Switch to BTC context */
176 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
177 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
178 }
179
esp_hf_client_stop_voice_recognition(void)180 esp_err_t esp_hf_client_stop_voice_recognition(void)
181 {
182 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
183 return ESP_ERR_INVALID_STATE;
184 }
185
186 btc_msg_t msg;
187
188 msg.sig = BTC_SIG_API_CALL;
189 msg.pid = BTC_PID_HF_CLIENT;
190 msg.act = BTC_HF_CLIENT_STOP_VOICE_RECOGNITION_EVT;
191
192 /* Switch to BTC context */
193 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
194 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
195 }
196
esp_hf_client_volume_update(esp_hf_volume_control_target_t type,int volume)197 esp_err_t esp_hf_client_volume_update(esp_hf_volume_control_target_t type, int volume)
198 {
199 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
200 return ESP_ERR_INVALID_STATE;
201 }
202
203 btc_msg_t msg;
204 btc_hf_client_args_t arg;
205
206 msg.sig = BTC_SIG_API_CALL;
207 msg.pid = BTC_PID_HF_CLIENT;
208 msg.act = BTC_HF_CLIENT_VOLUME_UPDATE_EVT;
209
210 memset(&arg, 0, sizeof(btc_hf_client_args_t));
211 arg.volume_update.type = type;
212 arg.volume_update.volume = volume;
213
214 /* Switch to BTC context */
215 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
216 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
217 }
218
esp_hf_client_dial(const char * number)219 esp_err_t esp_hf_client_dial(const char *number)
220 {
221 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
222 return ESP_ERR_INVALID_STATE;
223 }
224
225 btc_msg_t msg;
226 btc_hf_client_args_t arg;
227
228 if (number != NULL && strlen(number) > ESP_BT_HF_CLIENT_NUMBER_LEN) {
229 return ESP_ERR_INVALID_ARG;
230 }
231
232 msg.sig = BTC_SIG_API_CALL;
233 msg.pid = BTC_PID_HF_CLIENT;
234 msg.act = BTC_HF_CLIENT_DIAL_EVT;
235
236 memset(&arg, 0, sizeof(btc_hf_client_args_t));
237 if (number != NULL) {
238 strcpy(arg.dial.number, number);
239 } else {
240 arg.dial.number[0] = '\0';
241 }
242
243 /* Switch to BTC context */
244 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
245 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
246 }
247
esp_hf_client_dial_memory(int location)248 esp_err_t esp_hf_client_dial_memory(int location)
249 {
250 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
251 return ESP_ERR_INVALID_STATE;
252 }
253
254 btc_msg_t msg;
255 btc_hf_client_args_t arg;
256
257 msg.sig = BTC_SIG_API_CALL;
258 msg.pid = BTC_PID_HF_CLIENT;
259 msg.act = BTC_HF_CLIENT_DIAL_MEMORY_EVT;
260
261 memset(&arg, 0, sizeof(btc_hf_client_args_t));
262 arg.dial_memory.location = location;
263
264 /* Switch to BTC context */
265 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
266 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
267 }
268
esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld,int idx)269 esp_err_t esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld, int idx)
270 {
271 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
272 return ESP_ERR_INVALID_STATE;
273 }
274
275 btc_msg_t msg;
276 btc_hf_client_args_t arg;
277
278 msg.sig = BTC_SIG_API_CALL;
279 msg.pid = BTC_PID_HF_CLIENT;
280 msg.act = BTC_HF_CLIENT_SEND_CHLD_CMD_EVT;
281
282 memset(&arg, 0, sizeof(btc_hf_client_args_t));
283 arg.chld.type = chld;
284 arg.chld.idx = idx;
285
286 /* Switch to BTC context */
287 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
288 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
289 }
290
esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh)291 esp_err_t esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh)
292 {
293 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
294 return ESP_ERR_INVALID_STATE;
295 }
296
297 btc_msg_t msg;
298 btc_hf_client_args_t arg;
299
300 msg.sig = BTC_SIG_API_CALL;
301 msg.pid = BTC_PID_HF_CLIENT;
302 msg.act = BTC_HF_CLIENT_SEND_BTRH_CMD_EVT;
303
304 memset(&arg, 0, sizeof(btc_hf_client_args_t));
305 arg.btrh.cmd = btrh;
306
307 /* Switch to BTC context */
308 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
309 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
310 }
311
esp_hf_client_answer_call(void)312 esp_err_t esp_hf_client_answer_call(void)
313 {
314 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
315 return ESP_ERR_INVALID_STATE;
316 }
317
318 btc_msg_t msg;
319
320 msg.sig = BTC_SIG_API_CALL;
321 msg.pid = BTC_PID_HF_CLIENT;
322 msg.act = BTC_HF_CLIENT_ANSWER_CALL_EVT;
323
324 /* Switch to BTC context */
325 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
326 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
327 }
328
esp_hf_client_reject_call(void)329 esp_err_t esp_hf_client_reject_call(void)
330 {
331 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
332 return ESP_ERR_INVALID_STATE;
333 }
334
335 btc_msg_t msg;
336
337 msg.sig = BTC_SIG_API_CALL;
338 msg.pid = BTC_PID_HF_CLIENT;
339 msg.act = BTC_HF_CLIENT_REJECT_CALL_EVT;
340
341 /* Switch to BTC context */
342 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
343 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
344 }
345
esp_hf_client_query_current_calls(void)346 esp_err_t esp_hf_client_query_current_calls(void)
347 {
348 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
349 return ESP_ERR_INVALID_STATE;
350 }
351
352 btc_msg_t msg;
353
354 msg.sig = BTC_SIG_API_CALL;
355 msg.pid = BTC_PID_HF_CLIENT;
356 msg.act = BTC_HF_CLIENT_QUERY_CURRENT_CALLS_EVT;
357
358 /* Switch to BTC context */
359 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
360 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
361 }
362
esp_hf_client_query_current_operator_name(void)363 esp_err_t esp_hf_client_query_current_operator_name(void)
364 {
365 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
366 return ESP_ERR_INVALID_STATE;
367 }
368
369 btc_msg_t msg;
370
371 msg.sig = BTC_SIG_API_CALL;
372 msg.pid = BTC_PID_HF_CLIENT;
373 msg.act = BTC_HF_CLIENT_QUERY_CURRENT_OPERATOR_NAME_EVT;
374
375 /* Switch to BTC context */
376 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
377 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
378 }
379
esp_hf_client_retrieve_subscriber_info(void)380 esp_err_t esp_hf_client_retrieve_subscriber_info(void)
381 {
382 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
383 return ESP_ERR_INVALID_STATE;
384 }
385
386 btc_msg_t msg;
387
388 msg.sig = BTC_SIG_API_CALL;
389 msg.pid = BTC_PID_HF_CLIENT;
390 msg.act = BTC_HF_CLIENT_RETRIEVE_SUBSCRIBER_INFO_EVT;
391
392 /* Switch to BTC context */
393 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
394 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
395 }
396
esp_hf_client_send_dtmf(char code)397 esp_err_t esp_hf_client_send_dtmf(char code)
398 {
399 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
400 return ESP_ERR_INVALID_STATE;
401 }
402
403 btc_msg_t msg;
404 btc_hf_client_args_t arg;
405
406 msg.sig = BTC_SIG_API_CALL;
407 msg.pid = BTC_PID_HF_CLIENT;
408 msg.act = BTC_HF_CLIENT_SEND_DTMF_EVT;
409
410 memset(&arg, 0, sizeof(btc_hf_client_args_t));
411 arg.send_dtmf.code = code;
412
413 /* Switch to BTC context */
414 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
415 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
416 }
417
esp_hf_client_request_last_voice_tag_number(void)418 esp_err_t esp_hf_client_request_last_voice_tag_number(void)
419 {
420 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
421 return ESP_ERR_INVALID_STATE;
422 }
423
424 btc_msg_t msg;
425
426 msg.sig = BTC_SIG_API_CALL;
427 msg.pid = BTC_PID_HF_CLIENT;
428 msg.act = BTC_HF_CLIENT_REQUEST_LAST_VOICE_TAG_NUMBER_EVT;
429
430 /* Switch to BTC context */
431 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
432 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
433 }
434
esp_hf_client_send_nrec(void)435 esp_err_t esp_hf_client_send_nrec(void)
436 {
437 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
438 return ESP_ERR_INVALID_STATE;
439 }
440
441 btc_msg_t msg;
442 msg.sig = BTC_SIG_API_CALL;
443 msg.pid = BTC_PID_HF_CLIENT;
444 msg.act = BTC_HF_CLIENT_SEND_NREC_EVT;
445
446 /* Switch to BTC context */
447 bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
448 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
449 }
450
esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,esp_hf_client_outgoing_data_cb_t send)451 esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,
452 esp_hf_client_outgoing_data_cb_t send)
453 {
454 if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
455 return ESP_ERR_INVALID_STATE;
456 }
457
458 btc_msg_t msg;
459 msg.sig = BTC_SIG_API_CALL;
460 msg.pid = BTC_PID_HF_CLIENT;
461 msg.act = BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT;
462
463 btc_hf_client_args_t arg;
464 memset(&arg, 0, sizeof(btc_hf_client_args_t));
465 arg.reg_data_cb.recv = recv;
466 arg.reg_data_cb.send = send;
467
468 /* Switch to BTC context */
469 bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL);
470 return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
471 }
472
473
474 #if (BTM_SCO_HCI_INCLUDED == TRUE )
esp_hf_client_outgoing_data_ready(void)475 void esp_hf_client_outgoing_data_ready(void)
476 {
477 BTA_HfClientCiData();
478 }
479
esp_hf_client_pcm_resample_init(uint32_t src_sps,uint32_t bits,uint32_t channels)480 void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels)
481 {
482 BTA_DmPcmInitSamples(src_sps, bits, channels);
483 }
484
esp_hf_client_pcm_resample_deinit(void)485 void esp_hf_client_pcm_resample_deinit(void)
486 {
487 BTA_DmPcmDeinitSamples();
488 }
489
esp_hf_client_pcm_resample(void * src,uint32_t in_bytes,void * dst)490 int32_t esp_hf_client_pcm_resample(void *src, uint32_t in_bytes, void *dst)
491 {
492 return BTA_DmPcmResample(src, in_bytes, dst);
493 }
494
495 #endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */
496
497 #endif /* BTC_HF_CLIENT_INCLUDED */
498