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