1 /* hfp_hf.c - Hands free Profile - Handsfree side handling */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #include <ble_os.h>
9 #include <bt_errno.h>
10 #include <atomic.h>
11 #include <misc/byteorder.h>
12 #include <misc/util.h>
13 #include <misc/printk.h>
14 #ifdef CONFIG_BT_HFP_HF
15 #include <bluetooth/conn.h>
16
17 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HFP_HF)
18 #define LOG_MODULE_NAME bt_hfp_hf
19 /* FIXME: #include "common/log.h" */
20 #include <bluetooth/rfcomm.h>
21 #include <bluetooth/hfp_hf.h>
22
23 #include "hci_core.h"
24 #include "conn_internal.h"
25 #include "l2cap_internal.h"
26 #include "rfcomm_internal.h"
27 #include "at.h"
28 #include "hfp_internal.h"
29
30 #define MAX_IND_STR_LEN 17
31
32 struct bt_hfp_hf_cb *bt_hf;
33
34 NET_BUF_POOL_FIXED_DEFINE(hf_pool, CONFIG_BT_MAX_CONN + 1,
35 BT_RFCOMM_BUF_SIZE(BT_HF_CLIENT_MAX_PDU), NULL);
36
37 static struct bt_hfp_hf bt_hfp_hf_pool[CONFIG_BT_MAX_CONN];
38
39 /* The order should follow the enum hfp_hf_ag_indicators */
40 static const struct {
41 char *name;
42 bt_u32_t min;
43 bt_u32_t max;
44 } ag_ind[] = {
45 {"service", 0, 1}, /* HF_SERVICE_IND */
46 {"call", 0, 1}, /* HF_CALL_IND */
47 {"callsetup", 0, 3}, /* HF_CALL_SETUP_IND */
48 {"callheld", 0, 2}, /* HF_CALL_HELD_IND */
49 {"signal", 0, 5}, /* HF_SINGNAL_IND */
50 {"roam", 0, 1}, /* HF_ROAM_IND */
51 {"battchg", 0, 5} /* HF_BATTERY_IND */
52 };
53
hf_slc_error(struct at_client * hf_at)54 void hf_slc_error(struct at_client *hf_at)
55 {
56 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
57 int err;
58
59 BT_ERR("SLC error: disconnecting");
60 err = bt_rfcomm_dlc_disconnect(&hf->rfcomm_dlc);
61 if (err) {
62 BT_ERR("Rfcomm: Unable to disconnect :%d", -err);
63 }
64 }
65
hfp_hf_send_cmd(struct bt_hfp_hf * hf,at_resp_cb_t resp,at_finish_cb_t finish,const char * format,...)66 int hfp_hf_send_cmd(struct bt_hfp_hf *hf, at_resp_cb_t resp,
67 at_finish_cb_t finish, const char *format, ...)
68 {
69 struct net_buf *buf;
70 va_list vargs;
71 int ret;
72
73 /* register the callbacks */
74 at_register(&hf->at, resp, finish);
75
76 buf = bt_rfcomm_create_pdu(&hf_pool);
77 if (!buf) {
78 BT_ERR("No Buffers!");
79 return -ENOMEM;
80 }
81
82 va_start(vargs, format);
83 ret = vsnprintk(buf->data, (net_buf_tailroom(buf) - 1), format, vargs);
84 if (ret < 0) {
85 BT_ERR("Unable to format variable arguments");
86 return ret;
87 }
88 va_end(vargs);
89
90 net_buf_add(buf, ret);
91 net_buf_add_u8(buf, '\r');
92
93 ret = bt_rfcomm_dlc_send(&hf->rfcomm_dlc, buf);
94 if (ret < 0) {
95 BT_ERR("Rfcomm send error :(%d)", ret);
96 return ret;
97 }
98
99 return 0;
100 }
101
brsf_handle(struct at_client * hf_at)102 int brsf_handle(struct at_client *hf_at)
103 {
104 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
105 bt_u32_t val;
106 int ret;
107
108 ret = at_get_number(hf_at, &val);
109 if (ret < 0) {
110 BT_ERR("Error getting value");
111 return ret;
112 }
113
114 hf->ag_features = val;
115
116 return 0;
117 }
118
brsf_resp(struct at_client * hf_at,struct net_buf * buf)119 int brsf_resp(struct at_client *hf_at, struct net_buf *buf)
120 {
121 int err;
122
123 BT_DBG("");
124
125 err = at_parse_cmd_input(hf_at, buf, "BRSF", brsf_handle,
126 AT_CMD_TYPE_NORMAL);
127 if (err < 0) {
128 /* Returning negative value is avoided before SLC connection
129 * established.
130 */
131 BT_ERR("Error parsing CMD input");
132 hf_slc_error(hf_at);
133 }
134
135 return 0;
136 }
137
cind_handle_values(struct at_client * hf_at,bt_u32_t index,char * name,bt_u32_t min,bt_u32_t max)138 static void cind_handle_values(struct at_client *hf_at, bt_u32_t index,
139 char *name, bt_u32_t min, bt_u32_t max)
140 {
141 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
142 int i;
143
144 BT_DBG("index: %u, name: %s, min: %u, max:%u", index, name, min, max);
145
146 for (i = 0; i < ARRAY_SIZE(ag_ind); i++) {
147 if (strcmp(name, ag_ind[i].name) != 0) {
148 continue;
149 }
150 if (min != ag_ind[i].min || max != ag_ind[i].max) {
151 BT_ERR("%s indicator min/max value not matching", name);
152 }
153
154 hf->ind_table[index] = i;
155 break;
156 }
157 }
158
cind_handle(struct at_client * hf_at)159 int cind_handle(struct at_client *hf_at)
160 {
161 bt_u32_t index = 0U;
162
163 /* Parsing Example: CIND: ("call",(0,1)) etc.. */
164 while (at_has_next_list(hf_at)) {
165 char name[MAX_IND_STR_LEN];
166 bt_u32_t min, max;
167
168 if (at_open_list(hf_at) < 0) {
169 BT_ERR("Could not get open list");
170 goto error;
171 }
172
173 if (at_list_get_string(hf_at, name, sizeof(name)) < 0) {
174 BT_ERR("Could not get string");
175 goto error;
176 }
177
178 if (at_open_list(hf_at) < 0) {
179 BT_ERR("Could not get open list");
180 goto error;
181 }
182
183 if (at_list_get_range(hf_at, &min, &max) < 0) {
184 BT_ERR("Could not get range");
185 goto error;
186 }
187
188 if (at_close_list(hf_at) < 0) {
189 BT_ERR("Could not get close list");
190 goto error;
191 }
192
193 if (at_close_list(hf_at) < 0) {
194 BT_ERR("Could not get close list");
195 goto error;
196 }
197
198 cind_handle_values(hf_at, index, name, min, max);
199 index++;
200 }
201
202 return 0;
203 error:
204 BT_ERR("Error on CIND response");
205 hf_slc_error(hf_at);
206 return -EINVAL;
207 }
208
cind_resp(struct at_client * hf_at,struct net_buf * buf)209 int cind_resp(struct at_client *hf_at, struct net_buf *buf)
210 {
211 int err;
212
213 err = at_parse_cmd_input(hf_at, buf, "CIND", cind_handle,
214 AT_CMD_TYPE_NORMAL);
215 if (err < 0) {
216 BT_ERR("Error parsing CMD input");
217 hf_slc_error(hf_at);
218 }
219
220 return 0;
221 }
222
ag_indicator_handle_values(struct at_client * hf_at,bt_u32_t index,bt_u32_t value)223 void ag_indicator_handle_values(struct at_client *hf_at, bt_u32_t index,
224 bt_u32_t value)
225 {
226 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
227 struct bt_conn *conn = hf->rfcomm_dlc.session->br_chan.chan.conn;
228
229 BT_DBG("Index :%u, Value :%u", index, value);
230
231 if (index >= ARRAY_SIZE(ag_ind)) {
232 BT_ERR("Max only %lu indicators are supported",
233 ARRAY_SIZE(ag_ind));
234 return;
235 }
236
237 if (value > ag_ind[hf->ind_table[index]].max ||
238 value < ag_ind[hf->ind_table[index]].min) {
239 BT_ERR("Indicators out of range - value: %u", value);
240 return;
241 }
242
243 switch (hf->ind_table[index]) {
244 case HF_SERVICE_IND:
245 if (bt_hf->service) {
246 bt_hf->service(conn, value);
247 }
248 break;
249 case HF_CALL_IND:
250 if (bt_hf->call) {
251 bt_hf->call(conn, value);
252 }
253 break;
254 case HF_CALL_SETUP_IND:
255 if (bt_hf->call_setup) {
256 bt_hf->call_setup(conn, value);
257 }
258 break;
259 case HF_CALL_HELD_IND:
260 if (bt_hf->call_held) {
261 bt_hf->call_held(conn, value);
262 }
263 break;
264 case HF_SINGNAL_IND:
265 if (bt_hf->signal) {
266 bt_hf->signal(conn, value);
267 }
268 break;
269 case HF_ROAM_IND:
270 if (bt_hf->roam) {
271 bt_hf->roam(conn, value);
272 }
273 break;
274 case HF_BATTERY_IND:
275 if (bt_hf->battery) {
276 bt_hf->battery(conn, value);
277 }
278 break;
279 default:
280 BT_ERR("Unknown AG indicator");
281 break;
282 }
283 }
284
cind_status_handle(struct at_client * hf_at)285 int cind_status_handle(struct at_client *hf_at)
286 {
287 bt_u32_t index = 0U;
288
289 while (at_has_next_list(hf_at)) {
290 bt_u32_t value;
291 int ret;
292
293 ret = at_get_number(hf_at, &value);
294 if (ret < 0) {
295 BT_ERR("could not get the value");
296 return ret;
297 }
298
299 ag_indicator_handle_values(hf_at, index, value);
300
301 index++;
302 }
303
304 return 0;
305 }
306
cind_status_resp(struct at_client * hf_at,struct net_buf * buf)307 int cind_status_resp(struct at_client *hf_at, struct net_buf *buf)
308 {
309 int err;
310
311 err = at_parse_cmd_input(hf_at, buf, "CIND", cind_status_handle,
312 AT_CMD_TYPE_NORMAL);
313 if (err < 0) {
314 BT_ERR("Error parsing CMD input");
315 hf_slc_error(hf_at);
316 }
317
318 return 0;
319 }
320
ciev_handle(struct at_client * hf_at)321 int ciev_handle(struct at_client *hf_at)
322 {
323 bt_u32_t index, value;
324 int ret;
325
326 ret = at_get_number(hf_at, &index);
327 if (ret < 0) {
328 BT_ERR("could not get the Index");
329 return ret;
330 }
331 /* The first element of the list shall have 1 */
332 if (!index) {
333 BT_ERR("Invalid index value '0'");
334 return 0;
335 }
336
337 ret = at_get_number(hf_at, &value);
338 if (ret < 0) {
339 BT_ERR("could not get the value");
340 return ret;
341 }
342
343 ag_indicator_handle_values(hf_at, (index - 1), value);
344
345 return 0;
346 }
347
ring_handle(struct at_client * hf_at)348 int ring_handle(struct at_client *hf_at)
349 {
350 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
351 struct bt_conn *conn = hf->rfcomm_dlc.session->br_chan.chan.conn;
352
353 if (bt_hf->ring_indication) {
354 bt_hf->ring_indication(conn);
355 }
356
357 return 0;
358 }
359
360 static const struct unsolicited {
361 const char *cmd;
362 enum at_cmd_type type;
363 int (*func)(struct at_client *hf_at);
364 } handlers[] = {
365 { "CIEV", AT_CMD_TYPE_UNSOLICITED, ciev_handle },
366 { "RING", AT_CMD_TYPE_OTHER, ring_handle }
367 };
368
hfp_hf_unsol_lookup(struct at_client * hf_at)369 static const struct unsolicited *hfp_hf_unsol_lookup(struct at_client *hf_at)
370 {
371 int i;
372
373 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
374 if (!strncmp(hf_at->buf, handlers[i].cmd,
375 strlen(handlers[i].cmd))) {
376 return &handlers[i];
377 }
378 }
379
380 return NULL;
381 }
382
unsolicited_cb(struct at_client * hf_at,struct net_buf * buf)383 int unsolicited_cb(struct at_client *hf_at, struct net_buf *buf)
384 {
385 const struct unsolicited *handler;
386
387 handler = hfp_hf_unsol_lookup(hf_at);
388 if (!handler) {
389 BT_ERR("Unhandled unsolicited response");
390 return -ENOMSG;
391 }
392
393 if (!at_parse_cmd_input(hf_at, buf, handler->cmd, handler->func,
394 handler->type)) {
395 return 0;
396 }
397
398 return -ENOMSG;
399 }
400
cmd_complete(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)401 int cmd_complete(struct at_client *hf_at, enum at_result result,
402 enum at_cme cme_err)
403 {
404 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
405 struct bt_conn *conn = hf->rfcomm_dlc.session->br_chan.chan.conn;
406 struct bt_hfp_hf_cmd_complete cmd = { 0 };
407
408 BT_DBG("");
409
410 switch (result) {
411 case AT_RESULT_OK:
412 cmd.type = HFP_HF_CMD_OK;
413 break;
414 case AT_RESULT_ERROR:
415 cmd.type = HFP_HF_CMD_ERROR;
416 break;
417 case AT_RESULT_CME_ERROR:
418 cmd.type = HFP_HF_CMD_CME_ERROR;
419 cmd.cme = cme_err;
420 break;
421 default:
422 BT_ERR("Unknown error code");
423 cmd.type = HFP_HF_CMD_UNKNOWN_ERROR;
424 break;
425 }
426
427 if (bt_hf->cmd_complete_cb) {
428 bt_hf->cmd_complete_cb(conn, &cmd);
429 }
430
431 return 0;
432 }
433
cmee_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)434 int cmee_finish(struct at_client *hf_at, enum at_result result,
435 enum at_cme cme_err)
436 {
437 if (result != AT_RESULT_OK) {
438 BT_ERR("SLC Connection ERROR in response");
439 return -EINVAL;
440 }
441
442 return 0;
443 }
444
slc_completed(struct at_client * hf_at)445 static void slc_completed(struct at_client *hf_at)
446 {
447 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
448 struct bt_conn *conn = hf->rfcomm_dlc.session->br_chan.chan.conn;
449
450 if (bt_hf->connected) {
451 bt_hf->connected(conn);
452 }
453
454 if (hfp_hf_send_cmd(hf, NULL, cmee_finish, "AT+CMEE=1") < 0) {
455 BT_ERR("Error Sending AT+CMEE");
456 }
457 }
458
cmer_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)459 int cmer_finish(struct at_client *hf_at, enum at_result result,
460 enum at_cme cme_err)
461 {
462 if (result != AT_RESULT_OK) {
463 BT_ERR("SLC Connection ERROR in response");
464 hf_slc_error(hf_at);
465 return -EINVAL;
466 }
467
468 slc_completed(hf_at);
469
470 return 0;
471 }
472
cind_status_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)473 int cind_status_finish(struct at_client *hf_at, enum at_result result,
474 enum at_cme cme_err)
475 {
476 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
477 int err;
478
479 if (result != AT_RESULT_OK) {
480 BT_ERR("SLC Connection ERROR in response");
481 hf_slc_error(hf_at);
482 return -EINVAL;
483 }
484
485 at_register_unsolicited(hf_at, unsolicited_cb);
486 err = hfp_hf_send_cmd(hf, NULL, cmer_finish, "AT+CMER=3,0,0,1");
487 if (err < 0) {
488 hf_slc_error(hf_at);
489 return err;
490 }
491
492 return 0;
493 }
494
cind_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)495 int cind_finish(struct at_client *hf_at, enum at_result result,
496 enum at_cme cme_err)
497 {
498 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
499 int err;
500
501 if (result != AT_RESULT_OK) {
502 BT_ERR("SLC Connection ERROR in response");
503 hf_slc_error(hf_at);
504 return -EINVAL;
505 }
506
507 err = hfp_hf_send_cmd(hf, cind_status_resp, cind_status_finish,
508 "AT+CIND?");
509 if (err < 0) {
510 hf_slc_error(hf_at);
511 return err;
512 }
513
514 return 0;
515 }
516
brsf_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)517 int brsf_finish(struct at_client *hf_at, enum at_result result,
518 enum at_cme cme_err)
519 {
520 struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
521 int err;
522
523 if (result != AT_RESULT_OK) {
524 BT_ERR("SLC Connection ERROR in response");
525 hf_slc_error(hf_at);
526 return -EINVAL;
527 }
528
529 err = hfp_hf_send_cmd(hf, cind_resp, cind_finish, "AT+CIND=?");
530 if (err < 0) {
531 hf_slc_error(hf_at);
532 return err;
533 }
534
535 return 0;
536 }
537
hf_slc_establish(struct bt_hfp_hf * hf)538 int hf_slc_establish(struct bt_hfp_hf *hf)
539 {
540 int err;
541
542 BT_DBG("");
543
544 err = hfp_hf_send_cmd(hf, brsf_resp, brsf_finish, "AT+BRSF=%u",
545 hf->hf_features);
546 if (err < 0) {
547 hf_slc_error(&hf->at);
548 return err;
549 }
550
551 return 0;
552 }
553
bt_hfp_hf_lookup_bt_conn(struct bt_conn * conn)554 static struct bt_hfp_hf *bt_hfp_hf_lookup_bt_conn(struct bt_conn *conn)
555 {
556 int i;
557
558 for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
559 struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
560
561 if (hf->rfcomm_dlc.session->br_chan.chan.conn == conn) {
562 return hf;
563 }
564 }
565
566 return NULL;
567 }
568
bt_hfp_hf_send_cmd(struct bt_conn * conn,enum bt_hfp_hf_at_cmd cmd)569 int bt_hfp_hf_send_cmd(struct bt_conn *conn, enum bt_hfp_hf_at_cmd cmd)
570 {
571 struct bt_hfp_hf *hf;
572 int err;
573
574 BT_DBG("");
575
576 if (!conn) {
577 BT_ERR("Invalid connection");
578 return -ENOTCONN;
579 }
580
581 hf = bt_hfp_hf_lookup_bt_conn(conn);
582 if (!hf) {
583 BT_ERR("No HF connection found");
584 return -ENOTCONN;
585 }
586
587 switch (cmd) {
588 case BT_HFP_HF_ATA:
589 err = hfp_hf_send_cmd(hf, NULL, cmd_complete, "ATA");
590 if (err < 0) {
591 BT_ERR("Failed ATA");
592 return err;
593 }
594 break;
595 case BT_HFP_HF_AT_CHUP:
596 err = hfp_hf_send_cmd(hf, NULL, cmd_complete, "AT+CHUP");
597 if (err < 0) {
598 BT_ERR("Failed AT+CHUP");
599 return err;
600 }
601 break;
602 default:
603 BT_ERR("Invalid AT Command");
604 return -EINVAL;
605 }
606
607 return 0;
608 }
609
hfp_hf_connected(struct bt_rfcomm_dlc * dlc)610 static void hfp_hf_connected(struct bt_rfcomm_dlc *dlc)
611 {
612 struct bt_hfp_hf *hf = CONTAINER_OF(dlc, struct bt_hfp_hf, rfcomm_dlc);
613
614 BT_DBG("hf connected");
615
616 BT_ASSERT(hf);
617 hf_slc_establish(hf);
618 }
619
hfp_hf_disconnected(struct bt_rfcomm_dlc * dlc)620 static void hfp_hf_disconnected(struct bt_rfcomm_dlc *dlc)
621 {
622 struct bt_conn *conn = dlc->session->br_chan.chan.conn;
623
624 BT_DBG("hf disconnected!");
625 if (bt_hf->disconnected) {
626 bt_hf->disconnected(conn);
627 }
628 }
629
hfp_hf_recv(struct bt_rfcomm_dlc * dlc,struct net_buf * buf)630 static void hfp_hf_recv(struct bt_rfcomm_dlc *dlc, struct net_buf *buf)
631 {
632 struct bt_hfp_hf *hf = CONTAINER_OF(dlc, struct bt_hfp_hf, rfcomm_dlc);
633
634 if (at_parse_input(&hf->at, buf) < 0) {
635 BT_ERR("Parsing failed");
636 }
637 }
638
bt_hfp_hf_accept(struct bt_conn * conn,struct bt_rfcomm_dlc ** dlc)639 static int bt_hfp_hf_accept(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc)
640 {
641 int i;
642 static struct bt_rfcomm_dlc_ops ops = {
643 .connected = hfp_hf_connected,
644 .disconnected = hfp_hf_disconnected,
645 .recv = hfp_hf_recv,
646 };
647
648 BT_DBG("conn %p", conn);
649
650 for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
651 struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
652 int j;
653
654 if (hf->rfcomm_dlc.session) {
655 continue;
656 }
657
658 hf->at.buf = hf->hf_buffer;
659 hf->at.buf_max_len = HF_MAX_BUF_LEN;
660
661 hf->rfcomm_dlc.ops = &ops;
662 hf->rfcomm_dlc.mtu = BT_HFP_MAX_MTU;
663
664 *dlc = &hf->rfcomm_dlc;
665
666 /* Set the supported features*/
667 hf->hf_features = BT_HFP_HF_SUPPORTED_FEATURES;
668
669 for (j = 0; j < HF_MAX_AG_INDICATORS; j++) {
670 hf->ind_table[j] = -1;
671 }
672
673 return 0;
674 }
675
676 BT_ERR("Unable to establish HF connection (%p)", conn);
677
678 return -ENOMEM;
679 }
680
hfp_hf_init(void)681 static void hfp_hf_init(void)
682 {
683 static struct bt_rfcomm_server chan = {
684 .channel = BT_RFCOMM_CHAN_HFP_HF,
685 .accept = bt_hfp_hf_accept,
686 };
687
688 NET_BUF_POOL_INIT(hf_pool);
689
690 bt_rfcomm_server_register(&chan);
691 }
692
bt_hfp_hf_register(struct bt_hfp_hf_cb * cb)693 int bt_hfp_hf_register(struct bt_hfp_hf_cb *cb)
694 {
695 if (!cb) {
696 return -EINVAL;
697 }
698
699 if (bt_hf) {
700 return -EALREADY;
701 }
702
703 bt_hf = cb;
704
705 hfp_hf_init();
706
707 return 0;
708 }
709 #endif
710