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 <zephyr/kernel.h>
9 #include <errno.h>
10 #include <zephyr/sys/atomic.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/printk.h>
14 
15 #include <zephyr/bluetooth/conn.h>
16 
17 #include "common/assert.h"
18 
19 #include <zephyr/bluetooth/classic/rfcomm.h>
20 #include <zephyr/bluetooth/classic/hfp_hf.h>
21 #include <zephyr/bluetooth/classic/sdp.h>
22 
23 #include "host/hci_core.h"
24 #include "host/conn_internal.h"
25 #include "l2cap_br_internal.h"
26 #include "rfcomm_internal.h"
27 #include "at.h"
28 #include "sco_internal.h"
29 #include "hfp_internal.h"
30 
31 #define LOG_LEVEL CONFIG_BT_HFP_HF_LOG_LEVEL
32 #include <zephyr/logging/log.h>
33 LOG_MODULE_REGISTER(bt_hfp_hf);
34 
35 #define MAX_IND_STR_LEN 17
36 
37 struct bt_hfp_hf_cb *bt_hf;
38 
39 NET_BUF_POOL_FIXED_DEFINE(hf_pool, CONFIG_BT_MAX_CONN + 1,
40 			  BT_RFCOMM_BUF_SIZE(BT_HF_CLIENT_MAX_PDU),
41 			  CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
42 
43 static struct bt_hfp_hf bt_hfp_hf_pool[CONFIG_BT_MAX_CONN];
44 
45 /* The order should follow the enum hfp_hf_ag_indicators */
46 static const struct {
47 	char *name;
48 	uint32_t min;
49 	uint32_t max;
50 } ag_ind[] = {
51 	{"service", 0, 1}, /* HF_SERVICE_IND */
52 	{"call", 0, 1}, /* HF_CALL_IND */
53 	{"callsetup", 0, 3}, /* HF_CALL_SETUP_IND */
54 	{"callheld", 0, 2}, /* HF_CALL_HELD_IND */
55 	{"signal", 0, 5}, /* HF_SIGNAL_IND */
56 	{"roam", 0, 1}, /* HF_ROAM_IND */
57 	{"battchg", 0, 5} /* HF_BATTERY_IND */
58 };
59 
60 /* HFP Hands-Free SDP record */
61 static struct bt_sdp_attribute hfp_attrs[] = {
62 	BT_SDP_NEW_SERVICE,
63 	BT_SDP_LIST(
64 		BT_SDP_ATTR_SVCLASS_ID_LIST,
65 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
66 		BT_SDP_DATA_ELEM_LIST(
67 		{
68 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
69 			BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS)
70 		},
71 		{
72 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
73 			BT_SDP_ARRAY_16(BT_SDP_GENERIC_AUDIO_SVCLASS)
74 		}
75 		)
76 	),
77 	BT_SDP_LIST(
78 		BT_SDP_ATTR_PROTO_DESC_LIST,
79 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 12),
80 		BT_SDP_DATA_ELEM_LIST(
81 		{
82 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3),
83 			BT_SDP_DATA_ELEM_LIST(
84 			{
85 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
86 				BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP)
87 			},
88 			)
89 		},
90 		{
91 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 5),
92 			BT_SDP_DATA_ELEM_LIST(
93 			{
94 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
95 				BT_SDP_ARRAY_16(BT_SDP_PROTO_RFCOMM)
96 			},
97 			{
98 				BT_SDP_TYPE_SIZE(BT_SDP_UINT8),
99 				BT_SDP_ARRAY_8(BT_RFCOMM_CHAN_HFP_HF)
100 			},
101 			)
102 		},
103 		)
104 	),
105 	BT_SDP_LIST(
106 		BT_SDP_ATTR_PROFILE_DESC_LIST,
107 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
108 		BT_SDP_DATA_ELEM_LIST(
109 		{
110 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
111 			BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS)
112 		},
113 		{
114 			BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
115 			BT_SDP_ARRAY_16(0x0109)
116 		},
117 		)
118 	),
119 	/* The values of the “SupportedFeatures” bitmap shall be the same as the
120 	 * values of the Bits 0 to 4 of the AT-command AT+BRSF (see Section 5.3).
121 	 */
122 	BT_SDP_SUPPORTED_FEATURES(BT_HFP_HF_SUPPORTED_FEATURES & 0x1f),
123 };
124 
125 static struct bt_sdp_record hfp_rec = BT_SDP_RECORD(hfp_attrs);
126 
hf_slc_error(struct at_client * hf_at)127 void hf_slc_error(struct at_client *hf_at)
128 {
129 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
130 	int err;
131 
132 	LOG_ERR("SLC error: disconnecting");
133 	err = bt_rfcomm_dlc_disconnect(&hf->rfcomm_dlc);
134 	if (err) {
135 		LOG_ERR("Rfcomm: Unable to disconnect :%d", -err);
136 	}
137 }
138 
hfp_hf_send_cmd(struct bt_hfp_hf * hf,at_resp_cb_t resp,at_finish_cb_t finish,const char * format,...)139 int hfp_hf_send_cmd(struct bt_hfp_hf *hf, at_resp_cb_t resp,
140 		    at_finish_cb_t finish, const char *format, ...)
141 {
142 	struct net_buf *buf;
143 	va_list vargs;
144 	int ret;
145 
146 	/* register the callbacks */
147 	at_register(&hf->at, resp, finish);
148 
149 	buf = bt_rfcomm_create_pdu(&hf_pool);
150 	if (!buf) {
151 		LOG_ERR("No Buffers!");
152 		return -ENOMEM;
153 	}
154 
155 	va_start(vargs, format);
156 	ret = vsnprintk(buf->data, (net_buf_tailroom(buf) - 1), format, vargs);
157 	if (ret < 0) {
158 		LOG_ERR("Unable to format variable arguments");
159 		return ret;
160 	}
161 	va_end(vargs);
162 
163 	net_buf_add(buf, ret);
164 	net_buf_add_u8(buf, '\r');
165 
166 	LOG_DBG("HF %p, DLC %p sending buf %p", hf, &hf->rfcomm_dlc, buf);
167 
168 	ret = bt_rfcomm_dlc_send(&hf->rfcomm_dlc, buf);
169 	if (ret < 0) {
170 		LOG_ERR("Rfcomm send error :(%d)", ret);
171 		return ret;
172 	}
173 
174 	return 0;
175 }
176 
brsf_handle(struct at_client * hf_at)177 int brsf_handle(struct at_client *hf_at)
178 {
179 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
180 	uint32_t val;
181 	int ret;
182 
183 	ret = at_get_number(hf_at, &val);
184 	if (ret < 0) {
185 		LOG_ERR("Error getting value");
186 		return ret;
187 	}
188 
189 	hf->ag_features = val;
190 
191 	return 0;
192 }
193 
brsf_resp(struct at_client * hf_at,struct net_buf * buf)194 int brsf_resp(struct at_client *hf_at, struct net_buf *buf)
195 {
196 	int err;
197 
198 	LOG_DBG("");
199 
200 	err = at_parse_cmd_input(hf_at, buf, "BRSF", brsf_handle,
201 				 AT_CMD_TYPE_NORMAL);
202 	if (err < 0) {
203 		/* Returning negative value is avoided before SLC connection
204 		 * established.
205 		 */
206 		LOG_ERR("Error parsing CMD input");
207 		hf_slc_error(hf_at);
208 	}
209 
210 	return 0;
211 }
212 
cind_handle_values(struct at_client * hf_at,uint32_t index,char * name,uint32_t min,uint32_t max)213 static void cind_handle_values(struct at_client *hf_at, uint32_t index,
214 			       char *name, uint32_t min, uint32_t max)
215 {
216 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
217 	int i;
218 
219 	LOG_DBG("index: %u, name: %s, min: %u, max:%u", index, name, min, max);
220 
221 	for (i = 0; i < ARRAY_SIZE(ag_ind); i++) {
222 		if (strcmp(name, ag_ind[i].name) != 0) {
223 			continue;
224 		}
225 		if (min != ag_ind[i].min || max != ag_ind[i].max) {
226 			LOG_ERR("%s indicator min/max value not matching", name);
227 		}
228 
229 		hf->ind_table[index] = i;
230 		break;
231 	}
232 }
233 
cind_handle(struct at_client * hf_at)234 int cind_handle(struct at_client *hf_at)
235 {
236 	uint32_t index = 0U;
237 
238 	/* Parsing Example: CIND: ("call",(0,1)) etc.. */
239 	while (at_has_next_list(hf_at)) {
240 		char name[MAX_IND_STR_LEN];
241 		uint32_t min, max;
242 
243 		if (at_open_list(hf_at) < 0) {
244 			LOG_ERR("Could not get open list");
245 			goto error;
246 		}
247 
248 		if (at_list_get_string(hf_at, name, sizeof(name)) < 0) {
249 			LOG_ERR("Could not get string");
250 			goto error;
251 		}
252 
253 		if (at_open_list(hf_at) < 0) {
254 			LOG_ERR("Could not get open list");
255 			goto error;
256 		}
257 
258 		if (at_list_get_range(hf_at, &min, &max) < 0) {
259 			LOG_ERR("Could not get range");
260 			goto error;
261 		}
262 
263 		if (at_close_list(hf_at) < 0) {
264 			LOG_ERR("Could not get close list");
265 			goto error;
266 		}
267 
268 		if (at_close_list(hf_at) < 0) {
269 			LOG_ERR("Could not get close list");
270 			goto error;
271 		}
272 
273 		cind_handle_values(hf_at, index, name, min, max);
274 		index++;
275 	}
276 
277 	return 0;
278 error:
279 	LOG_ERR("Error on CIND response");
280 	hf_slc_error(hf_at);
281 	return -EINVAL;
282 }
283 
cind_resp(struct at_client * hf_at,struct net_buf * buf)284 int cind_resp(struct at_client *hf_at, struct net_buf *buf)
285 {
286 	int err;
287 
288 	err = at_parse_cmd_input(hf_at, buf, "CIND", cind_handle,
289 				 AT_CMD_TYPE_NORMAL);
290 	if (err < 0) {
291 		LOG_ERR("Error parsing CMD input");
292 		hf_slc_error(hf_at);
293 	}
294 
295 	return 0;
296 }
297 
ag_indicator_handle_values(struct at_client * hf_at,uint32_t index,uint32_t value)298 void ag_indicator_handle_values(struct at_client *hf_at, uint32_t index,
299 				uint32_t value)
300 {
301 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
302 	struct bt_conn *conn = hf->acl;
303 
304 	LOG_DBG("Index :%u, Value :%u", index, value);
305 
306 	if (index >= ARRAY_SIZE(ag_ind)) {
307 		LOG_ERR("Max only %zu indicators are supported", ARRAY_SIZE(ag_ind));
308 		return;
309 	}
310 
311 	if (value > ag_ind[hf->ind_table[index]].max ||
312 	    value < ag_ind[hf->ind_table[index]].min) {
313 		LOG_ERR("Indicators out of range - value: %u", value);
314 		return;
315 	}
316 
317 	switch (hf->ind_table[index]) {
318 	case HF_SERVICE_IND:
319 		if (bt_hf->service) {
320 			bt_hf->service(conn, value);
321 		}
322 		break;
323 	case HF_CALL_IND:
324 		if (bt_hf->call) {
325 			bt_hf->call(conn, value);
326 		}
327 		break;
328 	case HF_CALL_SETUP_IND:
329 		if (bt_hf->call_setup) {
330 			bt_hf->call_setup(conn, value);
331 		}
332 		break;
333 	case HF_CALL_HELD_IND:
334 		if (bt_hf->call_held) {
335 			bt_hf->call_held(conn, value);
336 		}
337 		break;
338 	case HF_SINGNAL_IND:
339 		if (bt_hf->signal) {
340 			bt_hf->signal(conn, value);
341 		}
342 		break;
343 	case HF_ROAM_IND:
344 		if (bt_hf->roam) {
345 			bt_hf->roam(conn, value);
346 		}
347 		break;
348 	case HF_BATTERY_IND:
349 		if (bt_hf->battery) {
350 			bt_hf->battery(conn, value);
351 		}
352 		break;
353 	default:
354 		LOG_ERR("Unknown AG indicator");
355 		break;
356 	}
357 }
358 
cind_status_handle(struct at_client * hf_at)359 int cind_status_handle(struct at_client *hf_at)
360 {
361 	uint32_t index = 0U;
362 
363 	while (at_has_next_list(hf_at)) {
364 		uint32_t value;
365 		int ret;
366 
367 		ret = at_get_number(hf_at, &value);
368 		if (ret < 0) {
369 			LOG_ERR("could not get the value");
370 			return ret;
371 		}
372 
373 		ag_indicator_handle_values(hf_at, index, value);
374 
375 		index++;
376 	}
377 
378 	return 0;
379 }
380 
cind_status_resp(struct at_client * hf_at,struct net_buf * buf)381 int cind_status_resp(struct at_client *hf_at, struct net_buf *buf)
382 {
383 	int err;
384 
385 	err = at_parse_cmd_input(hf_at, buf, "CIND", cind_status_handle,
386 				 AT_CMD_TYPE_NORMAL);
387 	if (err < 0) {
388 		LOG_ERR("Error parsing CMD input");
389 		hf_slc_error(hf_at);
390 	}
391 
392 	return 0;
393 }
394 
ciev_handle(struct at_client * hf_at)395 int ciev_handle(struct at_client *hf_at)
396 {
397 	uint32_t index, value;
398 	int ret;
399 
400 	ret = at_get_number(hf_at, &index);
401 	if (ret < 0) {
402 		LOG_ERR("could not get the Index");
403 		return ret;
404 	}
405 	/* The first element of the list shall have 1 */
406 	if (!index) {
407 		LOG_ERR("Invalid index value '0'");
408 		return 0;
409 	}
410 
411 	ret = at_get_number(hf_at, &value);
412 	if (ret < 0) {
413 		LOG_ERR("could not get the value");
414 		return ret;
415 	}
416 
417 	ag_indicator_handle_values(hf_at, (index - 1), value);
418 
419 	return 0;
420 }
421 
ring_handle(struct at_client * hf_at)422 int ring_handle(struct at_client *hf_at)
423 {
424 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
425 	struct bt_conn *conn = hf->acl;
426 
427 	if (bt_hf->ring_indication) {
428 		bt_hf->ring_indication(conn);
429 	}
430 
431 	return 0;
432 }
433 
434 static const struct unsolicited {
435 	const char *cmd;
436 	enum at_cmd_type type;
437 	int (*func)(struct at_client *hf_at);
438 } handlers[] = {
439 	{ "CIEV", AT_CMD_TYPE_UNSOLICITED, ciev_handle },
440 	{ "RING", AT_CMD_TYPE_OTHER, ring_handle }
441 };
442 
hfp_hf_unsol_lookup(struct at_client * hf_at)443 static const struct unsolicited *hfp_hf_unsol_lookup(struct at_client *hf_at)
444 {
445 	int i;
446 
447 	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
448 		if (!strncmp(hf_at->buf, handlers[i].cmd,
449 			     strlen(handlers[i].cmd))) {
450 			return &handlers[i];
451 		}
452 	}
453 
454 	return NULL;
455 }
456 
unsolicited_cb(struct at_client * hf_at,struct net_buf * buf)457 int unsolicited_cb(struct at_client *hf_at, struct net_buf *buf)
458 {
459 	const struct unsolicited *handler;
460 
461 	handler = hfp_hf_unsol_lookup(hf_at);
462 	if (!handler) {
463 		LOG_ERR("Unhandled unsolicited response");
464 		return -ENOMSG;
465 	}
466 
467 	if (!at_parse_cmd_input(hf_at, buf, handler->cmd, handler->func,
468 				handler->type)) {
469 		return 0;
470 	}
471 
472 	return -ENOMSG;
473 }
474 
cmd_complete(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)475 int cmd_complete(struct at_client *hf_at, enum at_result result,
476 	       enum at_cme cme_err)
477 {
478 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
479 	struct bt_conn *conn = hf->acl;
480 	struct bt_hfp_hf_cmd_complete cmd = { 0 };
481 
482 	LOG_DBG("");
483 
484 	switch (result) {
485 	case AT_RESULT_OK:
486 		cmd.type = HFP_HF_CMD_OK;
487 		break;
488 	case AT_RESULT_ERROR:
489 		cmd.type = HFP_HF_CMD_ERROR;
490 		break;
491 	case AT_RESULT_CME_ERROR:
492 		cmd.type = HFP_HF_CMD_CME_ERROR;
493 		cmd.cme = cme_err;
494 		break;
495 	default:
496 		LOG_ERR("Unknown error code");
497 		cmd.type = HFP_HF_CMD_UNKNOWN_ERROR;
498 		break;
499 	}
500 
501 	if (bt_hf->cmd_complete_cb) {
502 		bt_hf->cmd_complete_cb(conn, &cmd);
503 	}
504 
505 	return 0;
506 }
507 
cmee_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)508 int cmee_finish(struct at_client *hf_at, enum at_result result,
509 		enum at_cme cme_err)
510 {
511 	if (result != AT_RESULT_OK) {
512 		LOG_ERR("SLC Connection ERROR in response");
513 		return -EINVAL;
514 	}
515 
516 	return 0;
517 }
518 
slc_completed(struct at_client * hf_at)519 static void slc_completed(struct at_client *hf_at)
520 {
521 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
522 	struct bt_conn *conn = hf->acl;
523 
524 	if (bt_hf->connected) {
525 		bt_hf->connected(conn);
526 	}
527 
528 	if (hfp_hf_send_cmd(hf, NULL, cmee_finish, "AT+CMEE=1") < 0) {
529 		LOG_ERR("Error Sending AT+CMEE");
530 	}
531 }
532 
cmer_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)533 int cmer_finish(struct at_client *hf_at, enum at_result result,
534 		enum at_cme cme_err)
535 {
536 	if (result != AT_RESULT_OK) {
537 		LOG_ERR("SLC Connection ERROR in response");
538 		hf_slc_error(hf_at);
539 		return -EINVAL;
540 	}
541 
542 	slc_completed(hf_at);
543 
544 	return 0;
545 }
546 
cind_status_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)547 int cind_status_finish(struct at_client *hf_at, enum at_result result,
548 		       enum at_cme cme_err)
549 {
550 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
551 	int err;
552 
553 	if (result != AT_RESULT_OK) {
554 		LOG_ERR("SLC Connection ERROR in response");
555 		hf_slc_error(hf_at);
556 		return -EINVAL;
557 	}
558 
559 	at_register_unsolicited(hf_at, unsolicited_cb);
560 	err = hfp_hf_send_cmd(hf, NULL, cmer_finish, "AT+CMER=3,0,0,1");
561 	if (err < 0) {
562 		hf_slc_error(hf_at);
563 		return err;
564 	}
565 
566 	return 0;
567 }
568 
cind_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)569 int cind_finish(struct at_client *hf_at, enum at_result result,
570 		enum at_cme cme_err)
571 {
572 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
573 	int err;
574 
575 	if (result != AT_RESULT_OK) {
576 		LOG_ERR("SLC Connection ERROR in response");
577 		hf_slc_error(hf_at);
578 		return -EINVAL;
579 	}
580 
581 	err = hfp_hf_send_cmd(hf, cind_status_resp, cind_status_finish,
582 			      "AT+CIND?");
583 	if (err < 0) {
584 		hf_slc_error(hf_at);
585 		return err;
586 	}
587 
588 	return 0;
589 }
590 
brsf_finish(struct at_client * hf_at,enum at_result result,enum at_cme cme_err)591 int brsf_finish(struct at_client *hf_at, enum at_result result,
592 		enum at_cme cme_err)
593 {
594 	struct bt_hfp_hf *hf = CONTAINER_OF(hf_at, struct bt_hfp_hf, at);
595 	int err;
596 
597 	if (result != AT_RESULT_OK) {
598 		LOG_ERR("SLC Connection ERROR in response");
599 		hf_slc_error(hf_at);
600 		return -EINVAL;
601 	}
602 
603 	err = hfp_hf_send_cmd(hf, cind_resp, cind_finish, "AT+CIND=?");
604 	if (err < 0) {
605 		hf_slc_error(hf_at);
606 		return err;
607 	}
608 
609 	return 0;
610 }
611 
hf_slc_establish(struct bt_hfp_hf * hf)612 int hf_slc_establish(struct bt_hfp_hf *hf)
613 {
614 	int err;
615 
616 	LOG_DBG("");
617 
618 	err = hfp_hf_send_cmd(hf, brsf_resp, brsf_finish, "AT+BRSF=%u",
619 			      hf->hf_features);
620 	if (err < 0) {
621 		hf_slc_error(&hf->at);
622 		return err;
623 	}
624 
625 	return 0;
626 }
627 
bt_hfp_hf_lookup_bt_conn(struct bt_conn * conn)628 static struct bt_hfp_hf *bt_hfp_hf_lookup_bt_conn(struct bt_conn *conn)
629 {
630 	int i;
631 
632 	for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
633 		struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
634 
635 		if (hf->acl == conn) {
636 			return hf;
637 		}
638 	}
639 
640 	return NULL;
641 }
642 
bt_hfp_hf_send_cmd(struct bt_conn * conn,enum bt_hfp_hf_at_cmd cmd)643 int bt_hfp_hf_send_cmd(struct bt_conn *conn, enum bt_hfp_hf_at_cmd cmd)
644 {
645 	struct bt_hfp_hf *hf;
646 	int err;
647 
648 	LOG_DBG("");
649 
650 	if (!conn) {
651 		LOG_ERR("Invalid connection");
652 		return -ENOTCONN;
653 	}
654 
655 	hf = bt_hfp_hf_lookup_bt_conn(conn);
656 	if (!hf) {
657 		LOG_ERR("No HF connection found");
658 		return -ENOTCONN;
659 	}
660 
661 	switch (cmd) {
662 	case BT_HFP_HF_ATA:
663 		err = hfp_hf_send_cmd(hf, NULL, cmd_complete, "ATA");
664 		if (err < 0) {
665 			LOG_ERR("Failed ATA");
666 			return err;
667 		}
668 		break;
669 	case BT_HFP_HF_AT_CHUP:
670 		err = hfp_hf_send_cmd(hf, NULL, cmd_complete, "AT+CHUP");
671 		if (err < 0) {
672 			LOG_ERR("Failed AT+CHUP");
673 			return err;
674 		}
675 		break;
676 	default:
677 		LOG_ERR("Invalid AT Command");
678 		return -EINVAL;
679 	}
680 
681 	return 0;
682 }
683 
hfp_hf_connected(struct bt_rfcomm_dlc * dlc)684 static void hfp_hf_connected(struct bt_rfcomm_dlc *dlc)
685 {
686 	struct bt_hfp_hf *hf = CONTAINER_OF(dlc, struct bt_hfp_hf, rfcomm_dlc);
687 
688 	LOG_DBG("hf connected");
689 
690 	BT_ASSERT(hf);
691 	hf_slc_establish(hf);
692 }
693 
hfp_hf_disconnected(struct bt_rfcomm_dlc * dlc)694 static void hfp_hf_disconnected(struct bt_rfcomm_dlc *dlc)
695 {
696 	struct bt_hfp_hf *hf = CONTAINER_OF(dlc, struct bt_hfp_hf, rfcomm_dlc);
697 	struct bt_conn *conn = hf->acl;
698 
699 	LOG_DBG("hf disconnected!");
700 	if (bt_hf->disconnected) {
701 		bt_hf->disconnected(conn);
702 	}
703 }
704 
hfp_hf_recv(struct bt_rfcomm_dlc * dlc,struct net_buf * buf)705 static void hfp_hf_recv(struct bt_rfcomm_dlc *dlc, struct net_buf *buf)
706 {
707 	struct bt_hfp_hf *hf = CONTAINER_OF(dlc, struct bt_hfp_hf, rfcomm_dlc);
708 
709 	if (at_parse_input(&hf->at, buf) < 0) {
710 		LOG_ERR("Parsing failed");
711 	}
712 }
713 
hfp_hf_sent(struct bt_rfcomm_dlc * dlc,int err)714 static void hfp_hf_sent(struct bt_rfcomm_dlc *dlc, int err)
715 {
716 	LOG_DBG("DLC %p sent cb (err %d)", dlc, err);
717 }
718 
bt_hfp_hf_accept(struct bt_conn * conn,struct bt_rfcomm_dlc ** dlc)719 static int bt_hfp_hf_accept(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc)
720 {
721 	int i;
722 	static struct bt_rfcomm_dlc_ops ops = {
723 		.connected = hfp_hf_connected,
724 		.disconnected = hfp_hf_disconnected,
725 		.recv = hfp_hf_recv,
726 		.sent = hfp_hf_sent,
727 	};
728 
729 	LOG_DBG("conn %p", conn);
730 
731 	for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
732 		struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
733 		int j;
734 
735 		if (hf->rfcomm_dlc.session) {
736 			continue;
737 		}
738 
739 		hf->acl = conn;
740 		hf->at.buf = hf->hf_buffer;
741 		hf->at.buf_max_len = HF_MAX_BUF_LEN;
742 
743 		hf->rfcomm_dlc.ops = &ops;
744 		hf->rfcomm_dlc.mtu = BT_HFP_MAX_MTU;
745 
746 		*dlc = &hf->rfcomm_dlc;
747 
748 		/* Set the supported features*/
749 		hf->hf_features = BT_HFP_HF_SUPPORTED_FEATURES;
750 
751 		for (j = 0; j < HF_MAX_AG_INDICATORS; j++) {
752 			hf->ind_table[j] = -1;
753 		}
754 
755 		return 0;
756 	}
757 
758 	LOG_ERR("Unable to establish HF connection (%p)", conn);
759 
760 	return -ENOMEM;
761 }
762 
hfp_hf_sco_connected(struct bt_sco_chan * chan)763 static void hfp_hf_sco_connected(struct bt_sco_chan *chan)
764 {
765 	if ((bt_hf != NULL) && (bt_hf->sco_connected)) {
766 		bt_hf->sco_connected(chan->sco->sco.acl, chan->sco);
767 	}
768 }
769 
hfp_hf_sco_disconnected(struct bt_sco_chan * chan,uint8_t reason)770 static void hfp_hf_sco_disconnected(struct bt_sco_chan *chan, uint8_t reason)
771 {
772 	if ((bt_hf != NULL) && (bt_hf->sco_disconnected)) {
773 		bt_hf->sco_disconnected(chan->sco, reason);
774 	}
775 }
776 
bt_hfp_hf_sco_accept(const struct bt_sco_accept_info * info,struct bt_sco_chan ** chan)777 static int bt_hfp_hf_sco_accept(const struct bt_sco_accept_info *info,
778 		      struct bt_sco_chan **chan)
779 {
780 	int i;
781 	static struct bt_sco_chan_ops ops = {
782 		.connected = hfp_hf_sco_connected,
783 		.disconnected = hfp_hf_sco_disconnected,
784 	};
785 
786 	LOG_DBG("conn %p", info->acl);
787 
788 	for (i = 0; i < ARRAY_SIZE(bt_hfp_hf_pool); i++) {
789 		struct bt_hfp_hf *hf = &bt_hfp_hf_pool[i];
790 
791 		if (NULL == hf->rfcomm_dlc.session) {
792 			continue;
793 		}
794 
795 		if (info->acl != hf->rfcomm_dlc.session->br_chan.chan.conn) {
796 			continue;
797 		}
798 
799 		hf->chan.ops = &ops;
800 
801 		*chan = &hf->chan;
802 
803 		return 0;
804 	}
805 
806 	LOG_ERR("Unable to establish HF connection (%p)", info->acl);
807 
808 	return -ENOMEM;
809 }
810 
hfp_hf_init(void)811 static void hfp_hf_init(void)
812 {
813 	static struct bt_rfcomm_server chan = {
814 		.channel = BT_RFCOMM_CHAN_HFP_HF,
815 		.accept = bt_hfp_hf_accept,
816 	};
817 
818 	bt_rfcomm_server_register(&chan);
819 
820 	static struct bt_sco_server sco_server = {
821 		.sec_level = BT_SECURITY_L0,
822 		.accept = bt_hfp_hf_sco_accept,
823 	};
824 
825 	bt_sco_server_register(&sco_server);
826 
827 	bt_sdp_register_service(&hfp_rec);
828 }
829 
bt_hfp_hf_register(struct bt_hfp_hf_cb * cb)830 int bt_hfp_hf_register(struct bt_hfp_hf_cb *cb)
831 {
832 	if (!cb) {
833 		return -EINVAL;
834 	}
835 
836 	if (bt_hf) {
837 		return -EALREADY;
838 	}
839 
840 	bt_hf = cb;
841 
842 	hfp_hf_init();
843 
844 	return 0;
845 }
846