1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #include <sys/socket.h>
7 #include <syslog.h>
8 
9 #include "stdbool.h"
10 
11 #include "cras_bt_device.h"
12 #include "cras_bt_log.h"
13 #include "cras_observer.h"
14 #include "cras_telephony.h"
15 #include "cras_hfp_slc.h"
16 #include "cras_server_metrics.h"
17 #include "cras_system_state.h"
18 #include "cras_tm.h"
19 #include "cras_util.h"
20 
21 /* Message start and end with "\r\n". refer to spec 4.33. */
22 #define AT_CMD(cmd) "\r\n" cmd "\r\n"
23 
24 /* The timeout between event reporting and HF indicator commands */
25 #define HF_INDICATORS_TIMEOUT_MS 2000
26 /* The sleep time before reading and processing the following AT commands during
27  * codec connection setup.
28  */
29 #define CODEC_CONN_SLEEP_TIME_US 2000
30 #define SLC_BUF_SIZE_BYTES 256
31 
32 /* Indicator update command response and indicator indices.
33  * Note that indicator index starts from '1', index 0 is used for CRAS to record
34  * if the event report has been enabled or not.
35  */
36 #define CRAS_INDICATOR_ENABLE_INDEX 0
37 #define BATTERY_IND_INDEX 1
38 #define SIGNAL_IND_INDEX 2
39 #define SERVICE_IND_INDEX 3
40 #define CALL_IND_INDEX 4
41 #define CALLSETUP_IND_INDEX 5
42 #define CALLHELD_IND_INDEX 6
43 #define ROAM_IND_INDEX 7
44 #define INDICATOR_IND_MAX 8
45 #define INDICATOR_UPDATE_RSP                                                   \
46 	"+CIND: "                                                              \
47 	"(\"battchg\",(0-5)),"                                                 \
48 	"(\"signal\",(0-5)),"                                                  \
49 	"(\"service\",(0,1)),"                                                 \
50 	"(\"call\",(0,1)),"                                                    \
51 	"(\"callsetup\",(0-3)),"                                               \
52 	"(\"callheld\",(0-2)),"                                                \
53 	"(\"roam\",(0,1))"                                                     \
54 	""
55 /* Mode values for standard event reporting activation/deactivation AT
56  * command AT+CMER. Used for indicator events reporting in HFP. */
57 #define FORWARD_UNSOLICIT_RESULT_CODE 3
58 
59 /* Handle object to hold required info to initialize and maintain
60  * an HFP service level connection.
61  * Args:
62  *    buf - Buffer hold received commands.
63  *    buf_read_idx - Read index for buf.
64  *    buf_write_idx - Write index for buf.
65  *    rfcomm_fd - File descriptor for the established RFCOMM connection.
66  *    init_cb - Callback to be triggered when an SLC is initialized.
67  *    cli_active - Calling line identification notification is enabled or not.
68  *    battery - Current battery level of AG stored in SLC.
69  *    signal - Current signal strength of AG stored in SLC.
70  *    service - Current service availability of AG stored in SLC.
71  *    callheld - Current callheld status of AG stored in SLC.
72  *    ind_event_reports - Activate statuses of indicator events reporting.
73  *    ag_supported_features - Supported AG features bitmap.
74  *    hf_supported_features - Bit map of HF supported features.
75  *    hf_supports_battery_indicator - Bit map of battery indicator support of
76  *        connected HF.
77  *    hf_battery - Current battery level of HF reported by the HF. The data
78  *    range should be 0 ~ 100. Use -1 for no battery level reported.
79  *    preferred_codec - CVSD or mSBC based on the situation and strategy. This
80  *        needs not to be equal to selected_codec because codec negotiation
81  *        process may fail.
82  *    selected_codec - The codec id defaults to HFP_CODEC_UNUSED and changes
83  *        only if codec negotiation is supported and the negotiation flow
84  *        has completed.
85  *    telephony - A reference of current telephony handle.
86  *    device - The associated bt device.
87  */
88 struct hfp_slc_handle {
89 	char buf[SLC_BUF_SIZE_BYTES];
90 	int buf_read_idx;
91 	int buf_write_idx;
92 	int is_hsp;
93 	int rfcomm_fd;
94 	hfp_slc_init_cb init_cb;
95 	hfp_slc_disconnect_cb disconnect_cb;
96 	int cli_active;
97 	int battery;
98 	int signal;
99 	int service;
100 	int callheld;
101 	int ind_event_reports[INDICATOR_IND_MAX];
102 	int ag_supported_features;
103 	bool hf_codec_supported[HFP_MAX_CODECS];
104 	int hf_supported_features;
105 	int hf_supports_battery_indicator;
106 	int hf_battery;
107 	int preferred_codec;
108 	int selected_codec;
109 	struct cras_bt_device *device;
110 	struct cras_timer *timer;
111 
112 	struct cras_telephony_handle *telephony;
113 };
114 
115 /* AT command exchanges between AG(Audio gateway) and HF(Hands-free device) */
116 struct at_command {
117 	const char *cmd;
118 	int (*callback)(struct hfp_slc_handle *handle, const char *cmd);
119 };
120 
121 /* Sends a response or command to HF */
hfp_send(struct hfp_slc_handle * handle,const char * buf)122 static int hfp_send(struct hfp_slc_handle *handle, const char *buf)
123 {
124 	int written, err, len;
125 
126 	if (handle->rfcomm_fd < 0)
127 		return -EIO;
128 
129 	len = strlen(buf);
130 	written = 0;
131 	while (written < len) {
132 		err = write(handle->rfcomm_fd, buf + written, len - written);
133 		if (err < 0)
134 			return -errno;
135 		written += err;
136 	}
137 
138 	return 0;
139 }
140 
141 /* Sends a response for indicator event reporting. */
hfp_send_ind_event_report(struct hfp_slc_handle * handle,int ind_index,int value)142 static int hfp_send_ind_event_report(struct hfp_slc_handle *handle,
143 				     int ind_index, int value)
144 {
145 	char cmd[64];
146 
147 	if (handle->is_hsp ||
148 	    !handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] ||
149 	    !handle->ind_event_reports[ind_index])
150 		return 0;
151 
152 	snprintf(cmd, 64, AT_CMD("+CIEV: %d,%d"), ind_index, value);
153 	return hfp_send(handle, cmd);
154 }
155 
156 /* Sends calling line identification unsolicited result code and
157  * standard call waiting notification. */
hfp_send_calling_line_identification(struct hfp_slc_handle * handle,const char * number,int type)158 static int hfp_send_calling_line_identification(struct hfp_slc_handle *handle,
159 						const char *number, int type)
160 {
161 	char cmd[64];
162 
163 	if (handle->is_hsp)
164 		return 0;
165 
166 	if (handle->telephony->call) {
167 		snprintf(cmd, 64, AT_CMD("+CCWA: \"%s\",%d"), number, type);
168 	} else {
169 		snprintf(cmd, 64, AT_CMD("+CLIP: \"%s\",%d"), number, type);
170 	}
171 	return hfp_send(handle, cmd);
172 }
173 
174 /* ATA command to accept an incoming call. Mandatory support per spec 4.13. */
answer_call(struct hfp_slc_handle * handle,const char * cmd)175 static int answer_call(struct hfp_slc_handle *handle, const char *cmd)
176 {
177 	int rc;
178 	rc = hfp_send(handle, AT_CMD("OK"));
179 	if (rc)
180 		return rc;
181 
182 	return cras_telephony_event_answer_call();
183 }
184 
185 /* AT+CCWA command to enable the "Call Waiting notification" function.
186  * Mandatory support per spec 4.21. */
call_waiting_notify(struct hfp_slc_handle * handle,const char * buf)187 static int call_waiting_notify(struct hfp_slc_handle *handle, const char *buf)
188 {
189 	return hfp_send(handle, AT_CMD("OK"));
190 }
191 
192 /* AT+CLIP command to enable the "Calling Line Identification notification"
193  * function. Mandatory per spec 4.23.
194  */
cli_notification(struct hfp_slc_handle * handle,const char * cmd)195 static int cli_notification(struct hfp_slc_handle *handle, const char *cmd)
196 {
197 	if (strlen(cmd) < 9) {
198 		syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
199 		return hfp_send(handle, AT_CMD("ERROR"));
200 	}
201 	handle->cli_active = (cmd[8] == '1');
202 	return hfp_send(handle, AT_CMD("OK"));
203 }
204 
205 /* ATDdd...dd command to place call with supplied number, or ATD>nnn...
206  * command to dial the number stored at memory location. Mandatory per
207  * spec 4.18 and 4.19.
208  */
dial_number(struct hfp_slc_handle * handle,const char * cmd)209 static int dial_number(struct hfp_slc_handle *handle, const char *cmd)
210 {
211 	int rc, cmd_len;
212 
213 	cmd_len = strlen(cmd);
214 	if (cmd_len < 4)
215 		goto error_out;
216 
217 	if (cmd[3] == '>') {
218 		/* Handle memory dial. Extract memory location from command
219 		 * ATD>nnn...; and lookup. */
220 		int memory_location;
221 		memory_location = strtol(cmd + 4, NULL, 0);
222 		if (handle->telephony->dial_number == NULL ||
223 		    memory_location != 1)
224 			return hfp_send(handle, AT_CMD("ERROR"));
225 	} else {
226 		/* ATDddddd; Store dial number to the only memory slot. */
227 		cras_telephony_store_dial_number(cmd_len - 3 - 1, cmd + 3);
228 	}
229 
230 	rc = hfp_send(handle, AT_CMD("OK"));
231 	if (rc)
232 		return rc;
233 
234 	handle->telephony->callsetup = 2;
235 	return hfp_send_ind_event_report(handle, CALLSETUP_IND_INDEX, 2);
236 
237 error_out:
238 	syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
239 	return hfp_send(handle, AT_CMD("ERROR"));
240 }
241 
242 /* AT+VTS command to generate a DTMF code. Mandatory per spec 4.27. */
dtmf_tone(struct hfp_slc_handle * handle,const char * buf)243 static int dtmf_tone(struct hfp_slc_handle *handle, const char *buf)
244 {
245 	return hfp_send(handle, AT_CMD("OK"));
246 }
247 
248 /* Sends +BCS command to tell HF about our preferred codec. This shall
249  * be called only if codec negotiation is supported.
250  */
select_preferred_codec(struct hfp_slc_handle * handle)251 static void select_preferred_codec(struct hfp_slc_handle *handle)
252 {
253 	char buf[64];
254 	snprintf(buf, 64, AT_CMD("+BCS:%d"), handle->preferred_codec);
255 	hfp_send(handle, buf);
256 	BTLOG(btlog, BT_CODEC_SELECTION, 0, handle->preferred_codec);
257 }
258 
259 /* Marks SLC handle as initialized and trigger HFP AG's init_cb. */
initialize_slc_handle(struct cras_timer * timer,void * arg)260 static void initialize_slc_handle(struct cras_timer *timer, void *arg)
261 {
262 	struct hfp_slc_handle *handle = (struct hfp_slc_handle *)arg;
263 	if (timer)
264 		handle->timer = NULL;
265 
266 	if (handle->init_cb) {
267 		handle->init_cb(handle);
268 		handle->init_cb = NULL;
269 	}
270 }
271 
272 /* Handles the event that headset request to start a codec connection
273  * procedure.
274  */
bluetooth_codec_connection(struct hfp_slc_handle * handle,const char * cmd)275 static int bluetooth_codec_connection(struct hfp_slc_handle *handle,
276 				      const char *cmd)
277 {
278 	/* Reset current selected codec to force a new codec connection
279 	 * procedure when the next hfp_slc_codec_connection_setup is called.
280 	 */
281 	handle->selected_codec = HFP_CODEC_UNUSED;
282 	return hfp_send(handle, AT_CMD("OK"));
283 }
284 
285 /* Handles the event that headset request to select specific codec. */
bluetooth_codec_selection(struct hfp_slc_handle * handle,const char * cmd)286 static int bluetooth_codec_selection(struct hfp_slc_handle *handle,
287 				     const char *cmd)
288 {
289 	char *tokens = strdup(cmd);
290 	char *codec;
291 	int id, err;
292 
293 	strtok(tokens, "=");
294 	codec = strtok(NULL, ",");
295 	if (!codec)
296 		goto bcs_cmd_cleanup;
297 	id = atoi(codec);
298 	if ((id <= HFP_CODEC_UNUSED) || (id >= HFP_MAX_CODECS)) {
299 		syslog(LOG_ERR, "%s: invalid codec id: '%s'", __func__, cmd);
300 		free(tokens);
301 		return hfp_send(handle, AT_CMD("ERROR"));
302 	}
303 
304 	if (id != handle->preferred_codec)
305 		syslog(LOG_WARNING, "%s: inconsistent codec id: '%s'", __func__,
306 		       cmd);
307 
308 	BTLOG(btlog, BT_CODEC_SELECTION, 1, id);
309 	handle->selected_codec = id;
310 
311 bcs_cmd_cleanup:
312 	free(tokens);
313 	err = hfp_send(handle, AT_CMD("OK"));
314 	return err;
315 }
316 
317 /*
318  * AT+IPHONEACCEV command from HF to report state change.You can find details
319  * of this command in the Accessory Design Guidelines for Apple Devices R11
320  * section 16.1.
321  */
apple_accessory_state_change(struct hfp_slc_handle * handle,const char * cmd)322 static int apple_accessory_state_change(struct hfp_slc_handle *handle,
323 					const char *cmd)
324 {
325 	char *tokens, *num, *key, *val;
326 	int i, level;
327 
328 	/* AT+IPHONEACCEV=Number of key/value pairs,key1,val1,key2,val2,...
329 	 * Number of key/value pairs: The number of parameters coming next.
330 	 * key: the type of change being reported:
331          *      1 = Battery Level
332          *      2 = Dock State
333          * val: the value of the change:
334          * Battery Level: string value between '0' and '9'
335          * Dock State: 0 = undocked, 1 = docked
336 	 */
337 	tokens = strdup(cmd);
338 	strtok(tokens, "=");
339 	num = strtok(NULL, ",");
340 	if (!num) {
341 		free(tokens);
342 		return hfp_send(handle, AT_CMD("ERROR"));
343 	}
344 
345 	for (i = 0; i < atoi(num); i++) {
346 		key = strtok(NULL, ",");
347 		val = strtok(NULL, ",");
348 		if (!key || !val) {
349 			syslog(LOG_WARNING,
350 			       "IPHONEACCEV: Expected %d kv pairs but got %d",
351 			       atoi(num), i);
352 			break;
353 		}
354 
355 		if (atoi(key) == 1) {
356 			level = atoi(val);
357 			if (level >= 0 && level < 10) {
358 				cras_server_metrics_hfp_battery_report(
359 					CRAS_HFP_BATTERY_INDICATOR_APPLE);
360 				level = (level + 1) * 10;
361 				if (handle->hf_battery != level) {
362 					handle->hf_battery = level;
363 					cras_observer_notify_bt_battery_changed(
364 						cras_bt_device_address(
365 							handle->device),
366 						(uint32_t)(level));
367 				}
368 			} else {
369 				syslog(LOG_ERR,
370 				       "Get invalid battery status from cmd:%s",
371 				       cmd);
372 			}
373 		}
374 	}
375 	free(tokens);
376 	return hfp_send(handle, AT_CMD("OK"));
377 }
378 
379 /*
380  * AT+XAPL command from HF to enable Apple custom features. You can find details
381  * of it in the Accessory Design Guidelines for Apple Devices R11 section 15.1.
382  */
apple_supported_features(struct hfp_slc_handle * handle,const char * cmd)383 static int apple_supported_features(struct hfp_slc_handle *handle,
384 				    const char *cmd)
385 {
386 	char *tokens, *features;
387 	int apple_features, err;
388 	char buf[64];
389 
390 	/* AT+XAPL=<vendorID>-<productID>-<version>,<features>
391 	 * Parse <features>, the only token we care about.
392 	 */
393 	tokens = strdup(cmd);
394 	strtok(tokens, "=");
395 
396 	strtok(NULL, ",");
397 	features = strtok(NULL, ",");
398 	if (!features)
399 		goto error_out;
400 
401 	apple_features = atoi(features);
402 
403 	if (apple_features & APL_BATTERY)
404 		handle->hf_supports_battery_indicator |=
405 			CRAS_HFP_BATTERY_INDICATOR_APPLE;
406 
407 	snprintf(buf, 64, AT_CMD("+XAPL=iPhone,%d"),
408 		 CRAS_APL_SUPPORTED_FEATURES);
409 	err = hfp_send(handle, buf);
410 	if (err)
411 		goto error_out;
412 
413 	err = hfp_send(handle, AT_CMD("OK"));
414 	free(tokens);
415 	return err;
416 
417 error_out:
418 	syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
419 	free(tokens);
420 	return hfp_send(handle, AT_CMD("ERROR"));
421 }
422 
423 /* Handles the event when headset reports its available codecs list. */
available_codecs(struct hfp_slc_handle * handle,const char * cmd)424 static int available_codecs(struct hfp_slc_handle *handle, const char *cmd)
425 {
426 	char *tokens, *id_str;
427 	int id;
428 
429 	for (id = 0; id < HFP_MAX_CODECS; id++)
430 		handle->hf_codec_supported[id] = false;
431 
432 	tokens = strdup(cmd);
433 	strtok(tokens, "=");
434 	id_str = strtok(NULL, ",");
435 	while (id_str) {
436 		id = atoi(id_str);
437 		if ((id > HFP_CODEC_UNUSED) && (id < HFP_MAX_CODECS)) {
438 			handle->hf_codec_supported[id] = true;
439 			BTLOG(btlog, BT_AVAILABLE_CODECS, 0, id);
440 		}
441 		id_str = strtok(NULL, ",");
442 	}
443 
444 	if (hfp_slc_get_wideband_speech_supported(handle))
445 		handle->preferred_codec = HFP_CODEC_ID_MSBC;
446 	else
447 		handle->preferred_codec = HFP_CODEC_ID_CVSD;
448 
449 	free(tokens);
450 	return hfp_send(handle, AT_CMD("OK"));
451 }
452 
453 /* AT+CMER command enables the registration status update function in AG.
454  * The service level connection is consider initialized when successfully
455  * responded OK to the AT+CMER command. Mandatory support per spec 4.4.
456  */
event_reporting(struct hfp_slc_handle * handle,const char * cmd)457 static int event_reporting(struct hfp_slc_handle *handle, const char *cmd)
458 {
459 	char *tokens, *mode, *tmp;
460 	int err = 0;
461 
462 	/* AT+CMER=[<mode>[,<keyp>[,<disp>[,<ind> [,<bfr>]]]]]
463 	 * Parse <ind>, the only token we care about.
464 	 */
465 	tokens = strdup(cmd);
466 	strtok(tokens, "=");
467 
468 	mode = strtok(NULL, ",");
469 	tmp = strtok(NULL, ",");
470 	tmp = strtok(NULL, ",");
471 	tmp = strtok(NULL, ",");
472 
473 	/* mode = 3 for forward unsolicited result codes.
474 	 * AT+CMER=3,0,0,1 activates “indicator events reporting”.
475 	 * The service level connection is considered established after
476 	 * successfully responded with OK, regardless of the indicator
477 	 * events reporting status.
478 	 */
479 	if (!mode || !tmp) {
480 		syslog(LOG_ERR, "Invalid event reporting” cmd %s", cmd);
481 		err = -EINVAL;
482 		goto event_reporting_done;
483 	}
484 	if (atoi(mode) == FORWARD_UNSOLICIT_RESULT_CODE)
485 		handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] =
486 			atoi(tmp);
487 
488 	err = hfp_send(handle, AT_CMD("OK"));
489 	if (err) {
490 		syslog(LOG_ERR, "Error sending response for command %s", cmd);
491 		goto event_reporting_done;
492 	}
493 
494 	/*
495 	 * Wait for HF to retrieve information about HF indicators and consider
496 	 * the Service Level Connection to be fully initialized, and thereby
497 	 * established, if HF doesn't support HF indicators.
498 	 */
499 	if (hfp_slc_get_hf_hf_indicators_supported(handle))
500 		handle->timer =
501 			cras_tm_create_timer(cras_system_state_get_tm(),
502 					     HF_INDICATORS_TIMEOUT_MS,
503 					     initialize_slc_handle, handle);
504 	/*
505 	 * Otherwise, regard the Service Level Connection to be fully
506 	 * initialized and ready for the potential codec negotiation.
507 	 */
508 	else
509 		initialize_slc_handle(NULL, (void *)handle);
510 
511 event_reporting_done:
512 	free(tokens);
513 	return err;
514 }
515 
516 /* AT+CMEE command to set the "Extended Audio Gateway Error Result Code".
517  * Mandatory per spec 4.9.
518  */
extended_errors(struct hfp_slc_handle * handle,const char * buf)519 static int extended_errors(struct hfp_slc_handle *handle, const char *buf)
520 {
521 	return hfp_send(handle, AT_CMD("OK"));
522 }
523 
524 /* AT+CKPD command to handle the user initiated action from headset profile
525  * device.
526  */
key_press(struct hfp_slc_handle * handle,const char * buf)527 static int key_press(struct hfp_slc_handle *handle, const char *buf)
528 {
529 	hfp_send(handle, AT_CMD("OK"));
530 
531 	/* Release the call and connection. */
532 	if (handle->telephony->call || handle->telephony->callsetup) {
533 		cras_telephony_event_terminate_call();
534 		handle->disconnect_cb(handle);
535 		return -EIO;
536 	}
537 	return 0;
538 }
539 
540 /* AT+BLDN command to re-dial the last number. Mandatory support
541  * per spec 4.20.
542  */
last_dialed_number(struct hfp_slc_handle * handle,const char * buf)543 static int last_dialed_number(struct hfp_slc_handle *handle, const char *buf)
544 {
545 	int rc;
546 
547 	if (!handle->telephony->dial_number)
548 		return hfp_send(handle, AT_CMD("ERROR"));
549 
550 	rc = hfp_send(handle, AT_CMD("OK"));
551 	if (rc)
552 		return rc;
553 
554 	handle->telephony->callsetup = 2;
555 	return hfp_send_ind_event_report(handle, CALLSETUP_IND_INDEX, 2);
556 }
557 
558 /* AT+CLCC command to query list of current calls. Mandatory support
559  * per spec 4.31.
560  *
561  * +CLCC: <idx>,<direction>,<status>,<mode>,<multiparty>
562  */
list_current_calls(struct hfp_slc_handle * handle,const char * cmd)563 static int list_current_calls(struct hfp_slc_handle *handle, const char *cmd)
564 {
565 	char buf[64];
566 
567 	int idx = 1;
568 	int rc;
569 	/* Fake the call list base on callheld and call status
570 	 * since we have no API exposed to manage call list.
571 	 * This is a hack to pass qualification test which ask us to
572 	 * handle the basic case that one call is active and
573 	 * the other is on hold. */
574 	if (handle->telephony->callheld) {
575 		snprintf(buf, 64, AT_CMD("+CLCC: %d,1,1,0,0"), idx++);
576 		rc = hfp_send(handle, buf);
577 		if (rc)
578 			return rc;
579 	}
580 
581 	if (handle->telephony->call) {
582 		snprintf(buf, 64, AT_CMD("+CLCC: %d,1,0,0,0"), idx++);
583 		rc = hfp_send(handle, buf);
584 		if (rc)
585 			return rc;
586 	}
587 
588 	return hfp_send(handle, AT_CMD("OK"));
589 }
590 
591 /* AT+COPS command to query currently selected operator or set name format.
592  * Mandatory support per spec 4.8.
593  */
operator_selection(struct hfp_slc_handle * handle,const char * buf)594 static int operator_selection(struct hfp_slc_handle *handle, const char *buf)
595 {
596 	int rc;
597 	if (buf[7] == '?') {
598 		/* HF sends AT+COPS? command to find current network operator.
599 		 * AG responds with +COPS:<mode>,<format>,<operator>, where
600 		 * the mode=0 means automatic for network selection. If no
601 		 * operator is selected, <format> and <operator> are omitted.
602 		 */
603 		rc = hfp_send(handle, AT_CMD("+COPS: 0"));
604 		if (rc)
605 			return rc;
606 	}
607 	return hfp_send(handle, AT_CMD("OK"));
608 }
609 
610 /* The AT+CHLD command is used to control call hold, release, and multiparty
611  * states.
612  */
call_hold(struct hfp_slc_handle * handle,const char * buf)613 static int call_hold(struct hfp_slc_handle *handle, const char *buf)
614 {
615 	int rc;
616 
617 	// Chrome OS doesn't yet support CHLD features but we need to reply
618 	// the query with an empty feature list rather than "ERROR" to increase
619 	// interoperability with certain devices (b/172413440).
620 	if (strlen(buf) > 8 && buf[7] == '=' && buf[8] == '?') {
621 		rc = hfp_send(handle, AT_CMD("+CHLD:"));
622 		if (rc)
623 			return rc;
624 		return hfp_send(handle, AT_CMD("OK"));
625 	}
626 
627 	return hfp_send(handle, AT_CMD("ERROR"));
628 }
629 
630 /* AT+CIND command retrieves the supported indicator and its corresponding
631  * range and order index or read current status of indicators. Mandatory
632  * support per spec 4.2.
633  */
report_indicators(struct hfp_slc_handle * handle,const char * cmd)634 static int report_indicators(struct hfp_slc_handle *handle, const char *cmd)
635 {
636 	int err;
637 	char buf[64];
638 
639 	if (strlen(cmd) < 8) {
640 		syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
641 		return hfp_send(handle, AT_CMD("ERROR"));
642 	}
643 
644 	if (cmd[7] == '=') {
645 		/* Indicator update test command "AT+CIND=?" */
646 		err = hfp_send(handle, AT_CMD(INDICATOR_UPDATE_RSP));
647 	} else {
648 		/* Indicator update read command "AT+CIND?".
649 		 * Respond with current status of AG indicators,
650 		 * the values must be listed in the indicator order declared
651 		 * in INDICATOR_UPDATE_RSP.
652 		 * +CIND: <signal>,<service>,<call>,
653 		 *        <callsetup>,<callheld>,<roam>
654 		 */
655 		snprintf(buf, 64, AT_CMD("+CIND: %d,%d,%d,%d,%d,%d,0"),
656 			 handle->battery, handle->signal, handle->service,
657 			 handle->telephony->call, handle->telephony->callsetup,
658 			 handle->telephony->callheld);
659 		err = hfp_send(handle, buf);
660 	}
661 
662 	if (err < 0)
663 		return err;
664 
665 	return hfp_send(handle, AT_CMD("OK"));
666 }
667 
668 /* AT+BIA command to change the subset of indicators that shall be
669  * sent by the AG.
670  */
indicator_activation(struct hfp_slc_handle * handle,const char * cmd)671 static int indicator_activation(struct hfp_slc_handle *handle, const char *cmd)
672 {
673 	char *ptr;
674 	int idx = BATTERY_IND_INDEX;
675 
676 	/* AT+BIA=[[<indrep 1>][,[<indrep 2>][,...[,[<indrep n>]]]]]
677 	 * According to the spec:
678 	 * - The indicator state can be omitted and the current reporting
679 	 *   states of the indicator shall not change.
680 	 *     Ex: AT+BIA=,1,,0
681 	 *         Only the 2nd and 4th indicators may be affected.
682 	 * - HF can provide fewer indicators than AG and states not provided
683 	 *   shall not change.
684 	 *     Ex: CRAS supports 7 indicators and gets AT+BIA=1,0,1
685 	 *         Only the first three indicators may be affected.
686 	 * - Call, Call Setup and Held Call are mandatory and should be always
687 	 *   on no matter what state HF set.
688 	 */
689 	ptr = strchr(cmd, '=');
690 	while (ptr && idx < INDICATOR_IND_MAX) {
691 		if (idx != CALL_IND_INDEX && idx != CALLSETUP_IND_INDEX &&
692 		    idx != CALLHELD_IND_INDEX) {
693 			if (*(ptr + 1) == '1')
694 				handle->ind_event_reports[idx] = 1;
695 			else if (*(ptr + 1) == '0')
696 				handle->ind_event_reports[idx] = 0;
697 		}
698 		ptr = strchr(ptr + 1, ',');
699 		idx++;
700 	}
701 	return hfp_send(handle, AT_CMD("OK"));
702 }
703 
704 /* AT+BIND command to report, query and activate Generic Status Indicators.
705  * It is sent by the HF if both AG and HF support the HF indicator feature.
706  */
indicator_support(struct hfp_slc_handle * handle,const char * cmd)707 static int indicator_support(struct hfp_slc_handle *handle, const char *cmd)
708 {
709 	char *tokens, *key;
710 	int err, cmd_len;
711 
712 	cmd_len = strlen(cmd);
713 	if (cmd_len < 8)
714 		goto error_out;
715 
716 	if (cmd[7] == '=') {
717 		/* AT+BIND=? (Read AG supported indicators) */
718 		if (cmd_len > 8 && cmd[8] == '?') {
719 			/* +BIND: (<a>,<b>,<c>,...,<n>) (Response to AT+BIND=?)
720 			 * <a> ... <n>: 0-65535, entered as decimal unsigned
721 			 * integer values without leading zeros, referencing an
722 			 * HF indicator assigned number.
723 			 * 1 is for Enhanced Driver Status.
724 			 * 2 is for Battery Level.
725 			 * For the list of HF indicator assigned number, you can
726 			 * check the  Bluetooth SIG Assigned Numbers web page.
727 			 */
728 			BTLOG(btlog, BT_HFP_HF_INDICATOR, 1, 0);
729 			/* "2" is for HF Battery Level that we support. We don't
730 			 * support "1" but this is a workaround for Pixel Buds 2
731 			 * which expects this exact combination for battery
732 			 * reporting (HFP 1.7 standard) to work. This workaround
733 			 * is fine since we don't enable Safety Drive with
734 			 * +BIND: 1,1 (b/172680041).
735 			 */
736 			err = hfp_send(handle, AT_CMD("+BIND: (1,2)"));
737 			if (err < 0)
738 				return err;
739 		}
740 		/* AT+BIND=<a>,<b>,...,<n>(List HF supported indicators) */
741 		else {
742 			tokens = strdup(cmd);
743 			strtok(tokens, "=");
744 			key = strtok(NULL, ",");
745 			while (key != NULL) {
746 				if (atoi(key) == 2)
747 					handle->hf_supports_battery_indicator |=
748 						CRAS_HFP_BATTERY_INDICATOR_HFP;
749 				key = strtok(NULL, ",");
750 			}
751 			free(tokens);
752 		}
753 	}
754 	/* AT+BIND? (Read AG enabled/disabled status of indicators) */
755 	else if (cmd[7] == '?') {
756 		/* +BIND: <a>,<state> (Unsolicited or Response to AT+BIND?)
757 		 * This response enables the AG to notify the HF which HF
758 		 * indicators are supported and their state, enabled or
759 		 * disabled.
760 		 * <a>: 1 or 2, referencing an HF indicator assigned number.
761 		 * <state>: 0-1, entered as integer values, where
762 		 * 0 = disabled, no value changes shall be sent for this
763 		 * indicator
764 		 * 1 = enabled, value changes may be sent for this indicator
765 		 */
766 
767 		/* We don't support Enhanced Driver Status, so explicitly
768 		 * disable it (b/172680041).
769 		 */
770 		err = hfp_send(handle, AT_CMD("+BIND: 1,0"));
771 		if (err < 0)
772 			return err;
773 
774 		BTLOG(btlog, BT_HFP_HF_INDICATOR, 0, 0);
775 
776 		err = hfp_send(handle, AT_CMD("+BIND: 2,1"));
777 		if (err < 0)
778 			return err;
779 
780 		err = hfp_send(handle, AT_CMD("OK"));
781 		if (err)
782 			return err;
783 		/*
784 		 * Consider the Service Level Connection to be fully initialized
785 		 * and thereby established, after successfully responded with OK
786 		 */
787 		initialize_slc_handle(NULL, (void *)handle);
788 		return 0;
789 	} else {
790 		goto error_out;
791 	}
792 	/* This OK reply is required after both +BIND AT commands. It also
793 	 * covers the AT+BIND= <a>,<b>,...,<n> case.
794 	 */
795 	return hfp_send(handle, AT_CMD("OK"));
796 
797 error_out:
798 	syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
799 	return hfp_send(handle, AT_CMD("ERROR"));
800 }
801 
802 /* AT+BIEV command reports updated values of enabled HF indicators to the AG.
803  */
indicator_state_change(struct hfp_slc_handle * handle,const char * cmd)804 static int indicator_state_change(struct hfp_slc_handle *handle,
805 				  const char *cmd)
806 {
807 	char *tokens, *key, *val;
808 	int level;
809 	/* AT+BIEV= <assigned number>,<value> (Update value of indicator)
810 	 * CRAS only supports battery level, which is with assigned number 2.
811 	 * Battery level should range from 0 to 100 defined by the spec.
812 	 */
813 	tokens = strdup(cmd);
814 	strtok(tokens, "=");
815 	key = strtok(NULL, ",");
816 	if (!key)
817 		goto error_out;
818 
819 	if (atoi(key) == 2) {
820 		val = strtok(NULL, ",");
821 		if (!val)
822 			goto error_out;
823 		level = atoi(val);
824 		if (level >= 0 && level <= 100) {
825 			cras_server_metrics_hfp_battery_report(
826 				CRAS_HFP_BATTERY_INDICATOR_HFP);
827 			if (handle->hf_battery != level) {
828 				handle->hf_battery = level;
829 				cras_observer_notify_bt_battery_changed(
830 					cras_bt_device_address(handle->device),
831 					(uint32_t)(level));
832 			}
833 		} else {
834 			syslog(LOG_ERR,
835 			       "Get invalid battery status from cmd:%s", cmd);
836 		}
837 	} else {
838 		goto error_out;
839 	}
840 
841 	free(tokens);
842 	return hfp_send(handle, AT_CMD("OK"));
843 
844 error_out:
845 	syslog(LOG_WARNING, "%s: invalid command: '%s'", __func__, cmd);
846 	free(tokens);
847 	return hfp_send(handle, AT_CMD("ERROR"));
848 }
849 
850 /* AT+VGM and AT+VGS command reports the current mic and speaker gain
851  * level respectively. Optional support per spec 4.28.
852  */
signal_gain_setting(struct hfp_slc_handle * handle,const char * cmd)853 static int signal_gain_setting(struct hfp_slc_handle *handle, const char *cmd)
854 {
855 	int gain;
856 
857 	if (strlen(cmd) < 8) {
858 		syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
859 		return hfp_send(handle, AT_CMD("ERROR"));
860 	}
861 
862 	/* Map 0 to the smallest non-zero scale 6/100, and 15 to
863 	 * 100/100 full. */
864 	if (cmd[5] == 'S') {
865 		gain = atoi(&cmd[7]);
866 		if (gain < 0 || gain > 15) {
867 			syslog(LOG_ERR,
868 			       "signal_gain_setting: gain %d is not between 0 and 15",
869 			       gain);
870 			return hfp_send(handle, AT_CMD("ERROR"));
871 		}
872 		BTLOG(btlog, BT_HFP_UPDATE_SPEAKER_GAIN, gain, 0);
873 		cras_bt_device_update_hardware_volume(handle->device,
874 						      (gain + 1) * 100 / 16);
875 	}
876 
877 	return hfp_send(handle, AT_CMD("OK"));
878 }
879 
880 /* AT+CNUM command to query the subscriber number. Mandatory support
881  * per spec 4.30.
882  */
subscriber_number(struct hfp_slc_handle * handle,const char * buf)883 static int subscriber_number(struct hfp_slc_handle *handle, const char *buf)
884 {
885 	return hfp_send(handle, AT_CMD("OK"));
886 }
887 
888 /* AT+BRSF command notifies the HF(Hands-free device) supported features
889  * and retrieves the AG(Audio gateway) supported features. Mandatory
890  * support per spec 4.2.
891  */
supported_features(struct hfp_slc_handle * handle,const char * cmd)892 static int supported_features(struct hfp_slc_handle *handle, const char *cmd)
893 {
894 	int err;
895 	char response[128];
896 	char *tokens, *features;
897 
898 	if (strlen(cmd) < 9) {
899 		syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
900 		return hfp_send(handle, AT_CMD("ERROR"));
901 	}
902 
903 	tokens = strdup(cmd);
904 	strtok(tokens, "=");
905 	features = strtok(NULL, ",");
906 	if (!features)
907 		goto error_out;
908 
909 	handle->hf_supported_features = atoi(features);
910 	BTLOG(btlog, BT_HFP_SUPPORTED_FEATURES, 0,
911 	      handle->hf_supported_features);
912 	free(tokens);
913 
914 	/* AT+BRSF=<feature> command received, ignore the HF supported feature
915 	 * for now. Respond with +BRSF:<feature> to notify mandatory supported
916 	 * features in AG(audio gateway).
917 	 */
918 	BTLOG(btlog, BT_HFP_SUPPORTED_FEATURES, 1,
919 	      handle->ag_supported_features);
920 	snprintf(response, 128, AT_CMD("+BRSF: %u"),
921 		 handle->ag_supported_features);
922 	err = hfp_send(handle, response);
923 	if (err < 0)
924 		return err;
925 
926 	return hfp_send(handle, AT_CMD("OK"));
927 
928 error_out:
929 	free(tokens);
930 	syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
931 	return hfp_send(handle, AT_CMD("ERROR"));
932 }
933 
hfp_event_speaker_gain(struct hfp_slc_handle * handle,int gain)934 int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
935 {
936 	char command[128];
937 
938 	/* Normailize gain value to 0-15 */
939 	gain = gain * 15 / 100;
940 	BTLOG(btlog, BT_HFP_SET_SPEAKER_GAIN, gain, 0);
941 	snprintf(command, 128, AT_CMD("+VGS=%d"), gain);
942 
943 	return hfp_send(handle, command);
944 }
945 
946 /* AT+CHUP command to terminate current call. Mandatory support
947  * per spec 4.15.
948  */
terminate_call(struct hfp_slc_handle * handle,const char * cmd)949 static int terminate_call(struct hfp_slc_handle *handle, const char *cmd)
950 {
951 	int rc;
952 	rc = hfp_send(handle, AT_CMD("OK"));
953 	if (rc)
954 		return rc;
955 
956 	return cras_telephony_event_terminate_call();
957 }
958 
959 /* AT+XEVENT is defined by Android to support vendor specific features.
960  * Currently, the only known supported case for CrOS is the battery event sent
961  * by some Plantronics headsets.
962  */
vendor_specific_features(struct hfp_slc_handle * handle,const char * cmd)963 static int vendor_specific_features(struct hfp_slc_handle *handle,
964 				    const char *cmd)
965 {
966 	char *tokens, *event, *level_str, *num_of_level_str;
967 	int level, num_of_level;
968 
969 	tokens = strdup(cmd);
970 	strtok(tokens, "=");
971 	event = strtok(NULL, ",");
972 	if (!event)
973 		goto error_out;
974 
975 	/* AT+XEVENT=BATTERY,Level,NumberOfLevel,MinutesOfTalkTime,IsCharging
976 	 * Level: The charge level with a zero-based integer.
977 	 * NumberOfLevel: How many charging levels there are.
978 	 * MinuteOfTalkTime: The estimated number of talk minutes remaining.
979 	 * IsCharging: A 0 or 1 value.
980 	 *
981 	 * We only support the battery level and thus only care about the first
982 	 * 3 arguments.
983 	 */
984 	if (!strncmp(event, "BATTERY", 7)) {
985 		level_str = strtok(NULL, ",");
986 		num_of_level_str = strtok(NULL, ",");
987 		if (!level_str || !num_of_level_str)
988 			goto error_out;
989 
990 		level = atoi(level_str);
991 		num_of_level = atoi(num_of_level_str);
992 		if (level < 0 || num_of_level <= 1 || level >= num_of_level)
993 			goto error_out;
994 
995 		level = (int64_t)level * 100 / (num_of_level - 1);
996 		if (handle->hf_battery != level) {
997 			handle->hf_supports_battery_indicator |=
998 				CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS;
999 			cras_server_metrics_hfp_battery_report(
1000 				CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS);
1001 			handle->hf_battery = level;
1002 			cras_observer_notify_bt_battery_changed(
1003 				cras_bt_device_address(handle->device),
1004 				(uint32_t)(level));
1005 		}
1006 	}
1007 
1008 	free(tokens);
1009 	/* For Plantronic headsets, it is required to reply "OK" for the first
1010 	 * AT+XEVENT=USER-AGENT... command to tell the headset our support of
1011 	 * the xevent protocol. Otherwise, all following events including
1012 	 * BATTERY won't be sent.
1013 	 */
1014 	return hfp_send(handle, AT_CMD("OK"));
1015 
1016 error_out:
1017 	syslog(LOG_ERR, "%s: malformed vendor specific command: '%s'", __func__,
1018 	       cmd);
1019 	free(tokens);
1020 	return hfp_send(handle, AT_CMD("ERROR"));
1021 }
1022 
1023 /* AT commands to support in order to conform HFP specification.
1024  *
1025  * An initialized service level connection is the pre-condition for all
1026  * call related procedures. Note that for the call related commands,
1027  * we are good to just respond with a meaningless "OK".
1028  *
1029  * The procedure to establish a service level connection is described below:
1030  *
1031  * 1. HF notifies AG about its own supported features and AG responds
1032  * with its supported feature.
1033  *
1034  * HF(hands-free)                             AG(audio gateway)
1035  *                     AT+BRSF=<HF supported feature> -->
1036  *                 <-- +BRSF:<AG supported feature>
1037  *                 <-- OK
1038  *
1039  * 2. HF retrieves the information about the indicators supported in AG.
1040  *
1041  * HF(hands-free)                             AG(audio gateway)
1042  *                     AT+CIND=? -->
1043  *                 <-- +CIND:...
1044  *                 <-- OK
1045  *
1046  * 3. The HF requests the current status of the indicators in AG.
1047  *
1048  * HF(hands-free)                             AG(audio gateway)
1049  *                     AT+CIND -->
1050  *                 <-- +CIND:...
1051  *                 <-- OK
1052  *
1053  * 4. HF requests enabling indicator status update in the AG.
1054  *
1055  * HF(hands-free)                             AG(audio gateway)
1056  *                     AT+CMER= -->
1057  *                 <-- OK
1058  */
1059 static struct at_command at_commands[] = {
1060 	{ "ATA", answer_call },
1061 	{ "ATD", dial_number },
1062 	{ "AT+BAC", available_codecs },
1063 	{ "AT+BCC", bluetooth_codec_connection },
1064 	{ "AT+BCS", bluetooth_codec_selection },
1065 	{ "AT+BIA", indicator_activation },
1066 	{ "AT+BIEV", indicator_state_change },
1067 	{ "AT+BIND", indicator_support },
1068 	{ "AT+BLDN", last_dialed_number },
1069 	{ "AT+BRSF", supported_features },
1070 	{ "AT+CCWA", call_waiting_notify },
1071 	{ "AT+CHUP", terminate_call },
1072 	{ "AT+CIND", report_indicators },
1073 	{ "AT+CKPD", key_press },
1074 	{ "AT+CLCC", list_current_calls },
1075 	{ "AT+CLIP", cli_notification },
1076 	{ "AT+CMEE", extended_errors },
1077 	{ "AT+CMER", event_reporting },
1078 	{ "AT+CNUM", subscriber_number },
1079 	{ "AT+COPS", operator_selection },
1080 	{ "AT+IPHONEACCEV", apple_accessory_state_change },
1081 	{ "AT+VG", signal_gain_setting },
1082 	{ "AT+VTS", dtmf_tone },
1083 	{ "AT+XAPL", apple_supported_features },
1084 	{ "AT+XEVENT", vendor_specific_features },
1085 	{ "AT+CHLD", call_hold },
1086 	{ 0 }
1087 };
1088 
handle_at_command(struct hfp_slc_handle * slc_handle,const char * cmd)1089 static int handle_at_command(struct hfp_slc_handle *slc_handle, const char *cmd)
1090 {
1091 	struct at_command *atc;
1092 
1093 	for (atc = at_commands; atc->cmd; atc++)
1094 		if (!strncmp(cmd, atc->cmd, strlen(atc->cmd)))
1095 			return atc->callback(slc_handle, cmd);
1096 
1097 	syslog(LOG_DEBUG, "AT command %s not supported", cmd);
1098 	return hfp_send(slc_handle, AT_CMD("ERROR"));
1099 }
1100 
handle_at_command_for_test(struct hfp_slc_handle * slc_handle,const char * cmd)1101 int handle_at_command_for_test(struct hfp_slc_handle *slc_handle,
1102 			       const char *cmd)
1103 {
1104 	return handle_at_command(slc_handle, cmd);
1105 }
1106 
process_at_commands(struct hfp_slc_handle * handle)1107 static int process_at_commands(struct hfp_slc_handle *handle)
1108 {
1109 	ssize_t bytes_read;
1110 	int err;
1111 
1112 	bytes_read =
1113 		read(handle->rfcomm_fd, &handle->buf[handle->buf_write_idx],
1114 		     SLC_BUF_SIZE_BYTES - handle->buf_write_idx - 1);
1115 	if (bytes_read < 0)
1116 		return bytes_read;
1117 
1118 	handle->buf_write_idx += bytes_read;
1119 	handle->buf[handle->buf_write_idx] = '\0';
1120 
1121 	while (handle->buf_read_idx != handle->buf_write_idx) {
1122 		char *end_char;
1123 		end_char = strchr(&handle->buf[handle->buf_read_idx], '\r');
1124 		if (end_char == NULL)
1125 			break;
1126 
1127 		*end_char = '\0';
1128 		err = handle_at_command(handle,
1129 					&handle->buf[handle->buf_read_idx]);
1130 		if (err < 0)
1131 			return 0;
1132 
1133 		/* Shift the read index */
1134 		handle->buf_read_idx = 1 + end_char - handle->buf;
1135 		if (handle->buf_read_idx == handle->buf_write_idx) {
1136 			handle->buf_read_idx = 0;
1137 			handle->buf_write_idx = 0;
1138 		}
1139 	}
1140 
1141 	/* Handle the case when buffer is full and no command found. */
1142 	if (handle->buf_write_idx == SLC_BUF_SIZE_BYTES - 1) {
1143 		if (handle->buf_read_idx) {
1144 			memmove(handle->buf, &handle->buf[handle->buf_read_idx],
1145 				handle->buf_write_idx - handle->buf_read_idx);
1146 			handle->buf_write_idx -= handle->buf_read_idx;
1147 			handle->buf_read_idx = 0;
1148 		} else {
1149 			syslog(LOG_ERR,
1150 			       "Parse SLC command error, clean up buffer");
1151 			handle->buf_write_idx = 0;
1152 		}
1153 	}
1154 	return bytes_read;
1155 }
1156 
slc_watch_callback(void * arg,int revents)1157 static void slc_watch_callback(void *arg, int revents)
1158 {
1159 	struct hfp_slc_handle *handle = (struct hfp_slc_handle *)arg;
1160 	int err;
1161 
1162 	err = process_at_commands(handle);
1163 	if (err < 0) {
1164 		syslog(LOG_ERR, "Error reading slc command %s",
1165 		       strerror(errno));
1166 		cras_system_rm_select_fd(handle->rfcomm_fd);
1167 		handle->disconnect_cb(handle);
1168 	}
1169 	return;
1170 }
1171 
1172 /* Exported interfaces */
1173 
hfp_slc_create(int fd,int is_hsp,int ag_supported_features,struct cras_bt_device * device,hfp_slc_init_cb init_cb,hfp_slc_disconnect_cb disconnect_cb)1174 struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
1175 				      int ag_supported_features,
1176 				      struct cras_bt_device *device,
1177 				      hfp_slc_init_cb init_cb,
1178 				      hfp_slc_disconnect_cb disconnect_cb)
1179 {
1180 	struct hfp_slc_handle *handle;
1181 	int i;
1182 
1183 	if (!disconnect_cb)
1184 		return NULL;
1185 
1186 	handle = (struct hfp_slc_handle *)calloc(1, sizeof(*handle));
1187 	if (!handle)
1188 		return NULL;
1189 
1190 	handle->rfcomm_fd = fd;
1191 	handle->is_hsp = is_hsp;
1192 	handle->ag_supported_features = ag_supported_features;
1193 	handle->hf_supported_features = 0;
1194 	handle->device = device;
1195 	handle->init_cb = init_cb;
1196 	handle->disconnect_cb = disconnect_cb;
1197 	handle->cli_active = 0;
1198 	handle->battery = 5;
1199 	handle->signal = 5;
1200 	handle->service = 1;
1201 	handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] = 0;
1202 	for (i = BATTERY_IND_INDEX; i < INDICATOR_IND_MAX; i++)
1203 		handle->ind_event_reports[i] = 1;
1204 	handle->telephony = cras_telephony_get();
1205 	handle->preferred_codec = HFP_CODEC_ID_CVSD;
1206 	handle->selected_codec = HFP_CODEC_UNUSED;
1207 	handle->hf_supports_battery_indicator = CRAS_HFP_BATTERY_INDICATOR_NONE;
1208 	handle->hf_battery = -1;
1209 	cras_system_add_select_fd(handle->rfcomm_fd, slc_watch_callback, handle,
1210 				  POLLIN | POLLERR | POLLHUP);
1211 
1212 	return handle;
1213 }
1214 
hfp_slc_destroy(struct hfp_slc_handle * slc_handle)1215 void hfp_slc_destroy(struct hfp_slc_handle *slc_handle)
1216 {
1217 	cras_system_rm_select_fd(slc_handle->rfcomm_fd);
1218 	if (slc_handle->timer)
1219 		cras_tm_cancel_timer(cras_system_state_get_tm(),
1220 				     slc_handle->timer);
1221 	close(slc_handle->rfcomm_fd);
1222 	free(slc_handle);
1223 }
1224 
hfp_slc_is_hsp(struct hfp_slc_handle * handle)1225 int hfp_slc_is_hsp(struct hfp_slc_handle *handle)
1226 {
1227 	return handle->is_hsp;
1228 }
1229 
hfp_slc_get_selected_codec(struct hfp_slc_handle * handle)1230 int hfp_slc_get_selected_codec(struct hfp_slc_handle *handle)
1231 {
1232 	/* If codec negotiation is not supported on HF, or the negotiation
1233 	 * process never completed. Fallback to the preffered codec. */
1234 	if (handle->selected_codec == HFP_CODEC_UNUSED)
1235 		return handle->preferred_codec;
1236 	else
1237 		return handle->selected_codec;
1238 }
1239 
hfp_slc_codec_connection_setup(struct hfp_slc_handle * handle)1240 int hfp_slc_codec_connection_setup(struct hfp_slc_handle *handle)
1241 {
1242 	/* The time we wait for codec selection response. */
1243 	static struct timespec timeout = { 0, 100000000 };
1244 	struct pollfd poll_fd;
1245 	int rc = 0;
1246 	struct timespec ts = timeout;
1247 
1248 	/*
1249 	 * Codec negotiation is not required, if either AG or HF doesn't support
1250 	 * it or it has been done once.
1251 	 */
1252 	if (!hfp_slc_get_hf_codec_negotiation_supported(handle) ||
1253 	    !hfp_slc_get_ag_codec_negotiation_supported(handle) ||
1254 	    handle->selected_codec == handle->preferred_codec)
1255 		return 0;
1256 
1257 redo_codec_conn:
1258 	select_preferred_codec(handle);
1259 
1260 	poll_fd.fd = handle->rfcomm_fd;
1261 	poll_fd.events = POLLIN;
1262 
1263 	ts = timeout;
1264 	while (rc <= 0) {
1265 		rc = cras_poll(&poll_fd, 1, &ts, NULL);
1266 		if (rc == -ETIMEDOUT) {
1267 			/*
1268 	 		 * Catch the case that the first initial codec
1269 			 * negotiation timeout. At this point we're not sure
1270 			 * if HF is good with the preferred codec from AG.
1271 			 * Fallback to CVSD doesn't help because very likely
1272 			 * HF won't reply that either. The best thing we can
1273 			 * do is just leave a warning log.
1274 	 		 */
1275 			if (handle->selected_codec == HFP_CODEC_UNUSED) {
1276 				syslog(LOG_WARNING,
1277 				       "Proceed using codec %d without HF reply",
1278 				       handle->preferred_codec);
1279 			}
1280 			return rc;
1281 		}
1282 	}
1283 
1284 	if (rc > 0) {
1285 		do {
1286 			usleep(CODEC_CONN_SLEEP_TIME_US);
1287 			rc = process_at_commands(handle);
1288 		} while (rc == -EAGAIN);
1289 
1290 		if (rc <= 0)
1291 			return rc;
1292 		if (handle->selected_codec != handle->preferred_codec)
1293 			goto redo_codec_conn;
1294 	}
1295 
1296 	return 0;
1297 }
1298 
hfp_set_call_status(struct hfp_slc_handle * handle,int call)1299 int hfp_set_call_status(struct hfp_slc_handle *handle, int call)
1300 {
1301 	int old_call = handle->telephony->call;
1302 
1303 	if (old_call == call)
1304 		return 0;
1305 
1306 	handle->telephony->call = call;
1307 	return hfp_event_update_call(handle);
1308 }
1309 
1310 /* Procedure to setup a call when AG sees incoming call.
1311  *
1312  * HF(hands-free)                             AG(audio gateway)
1313  *                                                     <-- Incoming call
1314  *                 <-- +CIEV: (callsetup = 1)
1315  *                 <-- RING (ALERT)
1316  */
hfp_event_incoming_call(struct hfp_slc_handle * handle,const char * number,int type)1317 int hfp_event_incoming_call(struct hfp_slc_handle *handle, const char *number,
1318 			    int type)
1319 {
1320 	int rc;
1321 
1322 	if (handle->is_hsp)
1323 		return 0;
1324 
1325 	if (handle->cli_active) {
1326 		rc = hfp_send_calling_line_identification(handle, number, type);
1327 		if (rc)
1328 			return rc;
1329 	}
1330 
1331 	if (handle->telephony->call)
1332 		return 0;
1333 	else
1334 		return hfp_send(handle, AT_CMD("RING"));
1335 }
1336 
hfp_event_update_call(struct hfp_slc_handle * handle)1337 int hfp_event_update_call(struct hfp_slc_handle *handle)
1338 {
1339 	return hfp_send_ind_event_report(handle, CALL_IND_INDEX,
1340 					 handle->telephony->call);
1341 }
1342 
hfp_event_update_callsetup(struct hfp_slc_handle * handle)1343 int hfp_event_update_callsetup(struct hfp_slc_handle *handle)
1344 {
1345 	return hfp_send_ind_event_report(handle, CALLSETUP_IND_INDEX,
1346 					 handle->telephony->callsetup);
1347 }
1348 
hfp_event_update_callheld(struct hfp_slc_handle * handle)1349 int hfp_event_update_callheld(struct hfp_slc_handle *handle)
1350 {
1351 	return hfp_send_ind_event_report(handle, CALLHELD_IND_INDEX,
1352 					 handle->telephony->callheld);
1353 }
1354 
hfp_event_set_battery(struct hfp_slc_handle * handle,int level)1355 int hfp_event_set_battery(struct hfp_slc_handle *handle, int level)
1356 {
1357 	handle->battery = level;
1358 	return hfp_send_ind_event_report(handle, BATTERY_IND_INDEX, level);
1359 }
1360 
hfp_event_set_signal(struct hfp_slc_handle * handle,int level)1361 int hfp_event_set_signal(struct hfp_slc_handle *handle, int level)
1362 {
1363 	handle->signal = level;
1364 	return hfp_send_ind_event_report(handle, SIGNAL_IND_INDEX, level);
1365 }
1366 
hfp_event_set_service(struct hfp_slc_handle * handle,int avail)1367 int hfp_event_set_service(struct hfp_slc_handle *handle, int avail)
1368 {
1369 	/* Convert to 0 or 1.
1370 	 * Since the value must be either 1 or 0. (service presence or not) */
1371 	handle->service = !!avail;
1372 	return hfp_send_ind_event_report(handle, SERVICE_IND_INDEX, avail);
1373 }
1374 
hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle * handle)1375 int hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle *handle)
1376 {
1377 	return handle->ag_supported_features & AG_CODEC_NEGOTIATION;
1378 }
1379 
hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle * handle)1380 int hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle *handle)
1381 {
1382 	return handle->hf_supported_features & HF_CODEC_NEGOTIATION;
1383 }
1384 
hfp_slc_get_hf_hf_indicators_supported(struct hfp_slc_handle * handle)1385 int hfp_slc_get_hf_hf_indicators_supported(struct hfp_slc_handle *handle)
1386 {
1387 	return handle->hf_supported_features & HF_HF_INDICATORS;
1388 }
1389 
hfp_slc_get_wideband_speech_supported(struct hfp_slc_handle * handle)1390 bool hfp_slc_get_wideband_speech_supported(struct hfp_slc_handle *handle)
1391 {
1392 	return hfp_slc_get_ag_codec_negotiation_supported(handle) &&
1393 	       hfp_slc_get_hf_codec_negotiation_supported(handle) &&
1394 	       handle->hf_codec_supported[HFP_CODEC_ID_MSBC];
1395 }
1396 
hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle * handle)1397 int hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle *handle)
1398 {
1399 	return handle->hf_supports_battery_indicator;
1400 }
1401