1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright 2003-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #define LOG_TAG "bt_hf_client"
21
22 #include <bluetooth/log.h>
23
24 #include <cstddef>
25 #include <cstdint>
26 #include <cstdio>
27 #include <cstring>
28 #include <string>
29
30 #include "bta/hf_client/bta_hf_client_int.h"
31 #include "bta_hf_client_api.h"
32 #include "bta_hfp_api.h"
33 #include "bta_sys.h"
34 #include "btm_api_types.h"
35 #include "os/logging/log_adapter.h"
36 #include "osi/include/alarm.h"
37 #include "osi/include/allocator.h"
38 #include "osi/include/compat.h"
39 #include "osi/include/properties.h"
40 #include "power_mode.h"
41 #include "stack/include/acl_api.h"
42 #include "stack/include/port_api.h"
43
44 /* Uncomment to enable AT traffic dumping */
45 /* #define BTA_HF_CLIENT_AT_DUMP 1 */
46
47 /* minimum length of AT event */
48 #define BTA_HF_CLIENT_AT_EVENT_MIN_LEN 3
49
50 /* timeout (in milliseconds) for AT response */
51 #define BTA_HF_CLIENT_AT_TIMEOUT 29989
52
53 /* timeout (in milliseconds) for AT hold timer */
54 #define BTA_HF_CLIENT_AT_HOLD_TIMEOUT 41
55
56 // TODO(b/369381361) Enfore -Wmissing-prototypes
57 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
58
59 using namespace bluetooth;
60
61 static constexpr char kPropertyEnhancedDrivingIndicatorEnabled[] =
62 "bluetooth.headset_client.indicator.enhanced_driver_safety.enabled";
63
64 /******************************************************************************
65 * SUPPORTED EVENT MESSAGES
66 ******************************************************************************/
67
68 /* CIND: supported indicator names */
69 #define BTA_HF_CLIENT_INDICATOR_BATTERYCHG "battchg"
70 #define BTA_HF_CLIENT_INDICATOR_SIGNAL "signal"
71 #define BTA_HF_CLIENT_INDICATOR_SERVICE "service"
72 #define BTA_HF_CLIENT_INDICATOR_CALL "call"
73 #define BTA_HF_CLIENT_INDICATOR_ROAM "roam"
74 #define BTA_HF_CLIENT_INDICATOR_CALLSETUP "callsetup"
75 #define BTA_HF_CLIENT_INDICATOR_CALLHELD "callheld"
76
77 /* BIND parse mode */
78 #define BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND 0
79 #define BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND 1
80
81 #define MIN(a, b) \
82 ({ \
83 __typeof__(a) _a = (a); \
84 __typeof__(b) _b = (b); \
85 (_a < _b) ? _a : _b; \
86 })
87
88 /* CIND: represents each indicators boundaries */
89 typedef struct {
90 const char* name;
91 uint8_t min;
92 uint8_t max;
93 uint8_t namelen;
94 } tBTA_HF_CLIENT_INDICATOR;
95
96 #define BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT 7
97
98 /* CIND: storage room for indicators value range and their statuses */
99 static const tBTA_HF_CLIENT_INDICATOR
100 bta_hf_client_indicators[BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT] = {
101 /* name | min | max | name length -
102 used by parser */
103 {BTA_HF_CLIENT_INDICATOR_BATTERYCHG, 0, 5,
104 sizeof(BTA_HF_CLIENT_INDICATOR_BATTERYCHG)},
105 {BTA_HF_CLIENT_INDICATOR_SIGNAL, 0, 5, sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
106 {BTA_HF_CLIENT_INDICATOR_SERVICE, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
107 {BTA_HF_CLIENT_INDICATOR_CALL, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
108 {BTA_HF_CLIENT_INDICATOR_ROAM, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
109 {BTA_HF_CLIENT_INDICATOR_CALLSETUP, 0, 3,
110 sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
111 {BTA_HF_CLIENT_INDICATOR_CALLHELD, 0, 2, sizeof(BTA_HF_CLIENT_INDICATOR_CALLHELD)}};
112
113 /* +VGM/+VGS - gain min/max values */
114 #define BTA_HF_CLIENT_VGS_MIN 0
115 #define BTA_HF_CLIENT_VGS_MAX 15
116 #define BTA_HF_CLIENT_VGM_MIN 0
117 #define BTA_HF_CLIENT_VGM_MAX 15
118
119 uint32_t service_index = 0;
120 bool service_availability = true;
121 /* helper functions for handling AT commands queueing */
122
123 static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb);
124
bta_hf_client_clear_queued_at(tBTA_HF_CLIENT_CB * client_cb)125 static void bta_hf_client_clear_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
126 tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
127 tBTA_HF_CLIENT_AT_QCMD* next;
128
129 while (cur != NULL) {
130 next = cur->next;
131 osi_free(cur);
132 cur = next;
133 }
134
135 client_cb->at_cb.queued_cmd = NULL;
136 }
137
bta_hf_client_queue_at(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_CMD cmd,const char * buf,uint16_t buf_len)138 static void bta_hf_client_queue_at(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_CMD cmd,
139 const char* buf, uint16_t buf_len) {
140 tBTA_HF_CLIENT_AT_QCMD* new_cmd =
141 (tBTA_HF_CLIENT_AT_QCMD*)osi_malloc(sizeof(tBTA_HF_CLIENT_AT_QCMD));
142
143 log::verbose("cmd:{}", (int)cmd);
144
145 new_cmd->cmd = cmd;
146 new_cmd->buf_len = buf_len;
147 new_cmd->next = NULL;
148 memcpy(new_cmd->buf, buf, buf_len);
149
150 if (client_cb->at_cb.queued_cmd != NULL) {
151 tBTA_HF_CLIENT_AT_QCMD* qcmd = client_cb->at_cb.queued_cmd;
152
153 while (qcmd->next != NULL) {
154 qcmd = qcmd->next;
155 }
156
157 qcmd->next = new_cmd;
158 } else {
159 client_cb->at_cb.queued_cmd = new_cmd;
160 }
161 }
162
bta_hf_client_at_resp_timer_cback(void * data)163 static void bta_hf_client_at_resp_timer_cback(void* data) {
164 tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
165 if (client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_CNUM) {
166 log::info("timed out waiting for AT+CNUM response; spoofing OK.");
167 bta_hf_client_handle_ok(client_cb);
168 } else {
169 log::error("HFPClient: AT response timeout, disconnecting");
170
171 tBTA_HF_CLIENT_DATA msg = {};
172 msg.hdr.layer_specific = client_cb->handle;
173 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
174 }
175 }
176
bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB * client_cb)177 static void bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
178 alarm_set_on_mloop(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
179 bta_hf_client_at_resp_timer_cback, (void*)client_cb);
180 }
181
bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB * client_cb)182 static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
183 alarm_cancel(client_cb->at_cb.resp_timer);
184 }
185
bta_hf_client_send_at(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_CMD cmd,const char * buf,uint16_t buf_len)186 static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_CMD cmd,
187 const char* buf, uint16_t buf_len) {
188 log::verbose("{}", cmd);
189 if ((client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE || !client_cb->svc_conn) &&
190 !alarm_is_scheduled(client_cb->at_cb.hold_timer)) {
191 uint16_t len;
192
193 #ifdef BTA_HF_CLIENT_AT_DUMP
194 log::verbose("{:.{}}", buf, buf_len - 1);
195 #endif
196
197 client_cb->at_cb.current_cmd = cmd;
198 /* Generate fake responses for these because they won't reliably work */
199 if (!service_availability && (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) {
200 log::warn("No service, skipping {} command", cmd);
201 bta_hf_client_handle_ok(client_cb);
202 return;
203 }
204
205 log::verbose("writing port data to {}", client_cb->conn_handle);
206 if (PORT_WriteData(client_cb->conn_handle, buf, buf_len, &len) != PORT_SUCCESS) {
207 log::warn("Unable to write RFCOMM data peer:{} handle:{} len:{}", client_cb->peer_addr,
208 client_cb->conn_handle, buf_len);
209 };
210
211 bta_hf_client_start_at_resp_timer(client_cb);
212
213 return;
214 }
215
216 log::verbose("busy! queued: {}", cmd);
217 bta_hf_client_queue_at(client_cb, cmd, buf, buf_len);
218 }
219
bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB * client_cb)220 static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
221 tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
222
223 log::verbose("");
224
225 if (cur != NULL) {
226 client_cb->at_cb.queued_cmd = cur->next;
227
228 bta_hf_client_send_at(client_cb, cur->cmd, cur->buf, cur->buf_len);
229
230 osi_free(cur);
231 }
232 }
233
bta_hf_client_at_hold_timer_cback(void * data)234 static void bta_hf_client_at_hold_timer_cback(void* data) {
235 tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
236 log::verbose("");
237 bta_hf_client_send_queued_at(client_cb);
238 }
239
bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB * client_cb)240 static void bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
241 log::verbose("");
242 alarm_cancel(client_cb->at_cb.hold_timer);
243 }
244
bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB * client_cb)245 static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
246 log::verbose("");
247 alarm_set_on_mloop(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
248 bta_hf_client_at_hold_timer_cback, (void*)client_cb);
249 }
250
251 /******************************************************************************
252 *
253 * COMMON AT EVENT HANDLING funcS
254 *
255 * Receives data (strings, ints, etc.) from the parser and processes this
256 * data. No buffer parsing is being done here.
257 ******************************************************************************/
258
bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB * client_cb)259 static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) {
260 log::verbose("current_cmd:{}", client_cb->at_cb.current_cmd);
261
262 bta_hf_client_stop_at_resp_timer(client_cb);
263
264 if (!client_cb->svc_conn) {
265 bta_hf_client_slc_seq(client_cb, false);
266 return;
267 }
268
269 switch (client_cb->at_cb.current_cmd) {
270 case BTA_HF_CLIENT_AT_BIA:
271 case BTA_HF_CLIENT_AT_BCC:
272 case BTA_HF_CLIENT_AT_BIEV:
273 break;
274 case BTA_HF_CLIENT_AT_BCS:
275 bta_hf_client_start_at_hold_timer(client_cb);
276 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
277 return;
278 case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
279 if (!client_cb->send_at_reply) {
280 client_cb->send_at_reply = true;
281 }
282 break;
283 case BTA_HF_CLIENT_AT_NONE:
284 bta_hf_client_stop_at_hold_timer(client_cb);
285 break;
286 case BTA_HF_CLIENT_AT_ANDROID:
287 bta_hf_client_at_result(client_cb, BTA_HF_CLIENT_AT_RESULT_OK, 0);
288 break;
289 default:
290 if (client_cb->send_at_reply) {
291 bta_hf_client_at_result(client_cb, BTA_HF_CLIENT_AT_RESULT_OK, 0);
292 }
293 break;
294 }
295
296 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
297
298 bta_hf_client_send_queued_at(client_cb);
299 }
300
bta_hf_client_handle_error(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_RESULT_TYPE type,uint16_t cme)301 static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb,
302 tBTA_HF_CLIENT_AT_RESULT_TYPE type, uint16_t cme) {
303 log::verbose("type:{} cme:{} current_cmd:{}", type, cme, client_cb->at_cb.current_cmd);
304
305 bta_hf_client_stop_at_resp_timer(client_cb);
306
307 if (!client_cb->svc_conn) {
308 bta_hf_client_slc_seq(client_cb, true);
309 return;
310 }
311
312 switch (client_cb->at_cb.current_cmd) {
313 case BTA_HF_CLIENT_AT_BIA:
314 break;
315 case BTA_HF_CLIENT_AT_BCC:
316 case BTA_HF_CLIENT_AT_BCS:
317 bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
318 break;
319 case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
320 if (!client_cb->send_at_reply) {
321 client_cb->send_at_reply = true;
322 }
323 break;
324 case BTA_HF_CLIENT_AT_ANDROID:
325 bta_hf_client_at_result(client_cb, type, cme);
326 break;
327 default:
328 if (client_cb->send_at_reply) {
329 bta_hf_client_at_result(client_cb, type, cme);
330 }
331 break;
332 }
333
334 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
335
336 bta_hf_client_send_queued_at(client_cb);
337 }
338
bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB * client_cb)339 static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) {
340 log::verbose("");
341
342 const bool exit_sniff_while_ring =
343 osi_property_get_bool("bluetooth.headset_client.exit_sniff_while_ring", false);
344
345 // Invoke mode change to active mode if feature flag is enabled and current
346 // status is sniff
347 if (exit_sniff_while_ring) {
348 tBTM_PM_MODE mode;
349 if (BTM_ReadPowerMode(client_cb->peer_addr, &mode) && mode == BTM_PM_STS_SNIFF) {
350 bta_sys_busy(BTA_ID_HS, 1, client_cb->peer_addr);
351 }
352 }
353 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_RING_INDICATION, 0);
354 }
355
bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)356 static void bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) {
357 log::verbose("0x{:x}", value);
358 client_cb->peer_features = value;
359 }
360
361 /* handles a single indicator descriptor - registers it for value changing
362 * events */
bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB * client_cb,char * name,uint32_t min,uint32_t max,uint32_t index)363 static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb, char* name,
364 uint32_t min, uint32_t max, uint32_t index) {
365 uint8_t i = 0;
366
367 log::verbose("{} .{} <{}:{}>", index, name, min, max);
368
369 if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
370 return;
371 }
372
373 /* look for a matching indicator on list of supported ones */
374 for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
375 if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
376 service_index = index;
377 }
378 /* look for a match - search one sign further than indicators name to check
379 * for string end */
380 /* It will distinguish 'callheld' which could be matched by strncmp as
381 * 'call'. */
382 if (strncmp(name, bta_hf_client_indicators[i].name, bta_hf_client_indicators[i].namelen) != 0) {
383 continue;
384 }
385
386 /* index - enumerates value position in the incoming sequence */
387 /* if name matches one of the known indicators, add its incoming position */
388 /* to lookup table for easy value->indicator matching later, when only
389 * values come */
390 client_cb->at_cb.indicator_lookup[index] = i;
391
392 return;
393 }
394 }
395
bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB * client_cb,uint32_t index,uint32_t value)396 static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb, uint32_t index,
397 uint32_t value) {
398 log::verbose("index: {} value: {}", index, value);
399
400 if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
401 return;
402 }
403
404 if (service_index == index) {
405 if (value == 0) {
406 service_availability = false;
407 } else {
408 service_availability = true;
409 }
410 }
411 if (client_cb->at_cb.indicator_lookup[index] == -1) {
412 return;
413 }
414
415 /* get the real array index from lookup table */
416 index = client_cb->at_cb.indicator_lookup[index];
417
418 /* Ignore out of range values */
419 if (value > bta_hf_client_indicators[index].max || value < bta_hf_client_indicators[index].min) {
420 return;
421 }
422
423 /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
424 bta_hf_client_ind(client_cb, index, value);
425 }
426
bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB * client_cb,uint32_t mask)427 static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb, uint32_t mask) {
428 log::verbose("0x{:x}", mask);
429
430 client_cb->chld_features |= mask;
431 }
432
bta_hf_client_handle_bind_read_supported_ind(tBTA_HF_CLIENT_CB * client_cb,int indicator_id)433 static void bta_hf_client_handle_bind_read_supported_ind(tBTA_HF_CLIENT_CB* client_cb,
434 int indicator_id) {
435 log::verbose("{}", indicator_id);
436
437 client_cb->peer_hf_indicators.insert(indicator_id);
438 }
439
bta_hf_client_handle_bind_read_enabled_ind(tBTA_HF_CLIENT_CB * client_cb,int indicator_id,bool enable)440 static void bta_hf_client_handle_bind_read_enabled_ind(tBTA_HF_CLIENT_CB* client_cb,
441 int indicator_id, bool enable) {
442 log::verbose("{}", indicator_id);
443
444 if (enable) {
445 client_cb->enabled_hf_indicators.insert(indicator_id);
446 } else {
447 client_cb->enabled_hf_indicators.erase(indicator_id);
448 }
449 }
450
bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB * client_cb,uint32_t index,uint32_t value)451 static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb, uint32_t index,
452 uint32_t value) {
453 int8_t realind = -1;
454
455 log::verbose("index: {} value: {}", index, value);
456
457 if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
458 return;
459 }
460
461 if (service_index == index - 1) {
462 service_availability = value == 0 ? false : true;
463 }
464
465 realind = client_cb->at_cb.indicator_lookup[index - 1];
466
467 if (realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT) {
468 /* get the real in-array index from lookup table by index it comes at */
469 /* if there is no bug it should automatically be correctly calculated */
470 if (value > bta_hf_client_indicators[realind].max ||
471 value < bta_hf_client_indicators[realind].min) {
472 return;
473 }
474
475 /* update service availability on +ciev from AG. */
476 if (service_index == (index - 1)) {
477 if (value == 1) {
478 service_availability = true;
479 } else {
480 service_availability = false;
481 }
482 }
483
484 /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
485 bta_hf_client_ind(client_cb, realind, value);
486 }
487 }
488
bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)489 static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
490 tBTA_AG_UUID_CODEC uuid_codec = static_cast<tBTA_AG_UUID_CODEC>(codec);
491 log::verbose("codec: {} sco listen state: {}", codec, client_cb->sco_state);
492 if (uuid_codec == tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD ||
493 uuid_codec == tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC ||
494 (bta_hf_client_cb_arr.is_support_lc3 && uuid_codec == tBTA_AG_UUID_CODEC::UUID_CODEC_LC3)) {
495 switch (uuid_codec) {
496 case tBTA_AG_UUID_CODEC::UUID_CODEC_CVSD:
497 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
498 break;
499 case tBTA_AG_UUID_CODEC::UUID_CODEC_MSBC:
500 client_cb->negotiated_codec = BTM_SCO_CODEC_MSBC;
501 break;
502 case tBTA_AG_UUID_CODEC::UUID_CODEC_LC3:
503 client_cb->negotiated_codec = BTM_SCO_CODEC_LC3;
504 break;
505 default:
506 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
507 break;
508 }
509 bta_hf_client_send_at_bcs(client_cb, codec);
510 } else {
511 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
512 bta_hf_client_send_at_bac(client_cb);
513 }
514 }
515
bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB * client_cb,uint32_t provided)516 static void bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB* client_cb, uint32_t provided) {
517 log::verbose("{}", provided);
518
519 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BSIR_EVT, provided);
520 }
521
bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB * client_cb,uint32_t code)522 static void bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB* client_cb, uint32_t code) {
523 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_CME, code);
524 }
525
bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)526 static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) {
527 log::verbose("{}", value);
528
529 if (value <= BTA_HF_CLIENT_VGM_MAX) {
530 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_MIC_EVT, value);
531 }
532 }
533
bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)534 static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) {
535 log::verbose("{}", value);
536
537 if (value <= BTA_HF_CLIENT_VGS_MAX) {
538 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_SPK_EVT, value);
539 }
540 }
541
bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)542 static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb, uint32_t value) {
543 log::verbose("{}", value);
544
545 if (value > 1) {
546 return;
547 }
548
549 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_VOICE_REC_EVT, value);
550 }
551
bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint32_t type)552 static void bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint32_t type) {
553 std::string cell_number(numstr);
554 log::verbose("{} {}", type, PRIVATE_CELL(cell_number));
555
556 bta_hf_client_clip(client_cb, numstr);
557 }
558
bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint32_t type)559 static void bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint32_t type) {
560 std::string cell_number(numstr);
561 log::verbose("{} {}", type, PRIVATE_CELL(cell_number));
562
563 bta_hf_client_ccwa(client_cb, numstr);
564 }
565
bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB * client_cb,char * opstr,uint32_t mode)566 static void bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB* client_cb, char* opstr, uint32_t mode) {
567 log::verbose("{} {}", mode, opstr);
568
569 bta_hf_client_operator_name(client_cb, opstr);
570 }
571
bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB * client_cb,char * numstr)572 static void bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB* client_cb, char* numstr) {
573 std::string cell_number(numstr);
574 log::verbose("{}", PRIVATE_CELL(cell_number));
575
576 bta_hf_client_binp(client_cb, numstr);
577 }
578
bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB * client_cb,uint16_t idx,uint16_t dir,uint16_t status,uint16_t mode,uint16_t mpty,char * numstr,uint16_t type)579 static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb, uint16_t idx, uint16_t dir,
580 uint16_t status, uint16_t mode, uint16_t mpty, char* numstr,
581 uint16_t type) {
582 log::verbose("idx: {} dir: {} status: {} mode: {} mpty: {}", idx, dir, status, mode, mpty);
583
584 if (numstr) {
585 std::string cell_number(numstr);
586 log::verbose("number: {} type: {}", PRIVATE_CELL(cell_number), type);
587 }
588
589 bta_hf_client_clcc(client_cb, idx, dir, status, mpty, numstr);
590 }
591
bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint16_t type,uint16_t service)592 static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb, char* numstr, uint16_t type,
593 uint16_t service) {
594 std::string cell_number(numstr);
595 log::verbose("number: {} type: {} service: {}", PRIVATE_CELL(cell_number), type, service);
596
597 /* TODO: should number be modified according to type? */
598 bta_hf_client_cnum(client_cb, numstr, service);
599 }
600
bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB * client_cb,uint16_t code)601 static void bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB* client_cb, uint16_t code) {
602 log::verbose("{}", code);
603
604 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BTRH_EVT, code);
605 }
606
607 /*******************************************************************************
608 *
609 * Function bta_hf_client_cback_ind
610 *
611 * Description Send indicator callback event to application.
612 *
613 * Returns void
614 *
615 ******************************************************************************/
bta_hf_client_ind(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_IND_TYPE type,uint16_t value)616 void bta_hf_client_ind(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_IND_TYPE type, uint16_t value) {
617 tBTA_HF_CLIENT evt;
618
619 memset(&evt, 0, sizeof(evt));
620
621 evt.ind.type = type;
622 evt.ind.value = value;
623
624 evt.ind.bd_addr = client_cb->peer_addr;
625 bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
626 }
627
628 /*******************************************************************************
629 *
630 * Function bta_hf_client_evt_val
631 *
632 * Description Send event to application.
633 * This is a generic helper for events with common data.
634 *
635 *
636 * Returns void
637 *
638 ******************************************************************************/
bta_hf_client_evt_val(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_EVT type,uint16_t value)639 void bta_hf_client_evt_val(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_EVT type, uint16_t value) {
640 tBTA_HF_CLIENT evt;
641
642 memset(&evt, 0, sizeof(evt));
643
644 evt.val.bd_addr = client_cb->peer_addr;
645 evt.val.value = value;
646
647 bta_hf_client_app_callback(type, &evt);
648 }
649
650 /*******************************************************************************
651 *
652 * Function bta_hf_client_operator_name
653 *
654 * Description Send operator name event to application.
655 *
656 *
657 * Returns void
658 *
659 ******************************************************************************/
bta_hf_client_operator_name(tBTA_HF_CLIENT_CB * client_cb,char * name)660 void bta_hf_client_operator_name(tBTA_HF_CLIENT_CB* client_cb, char* name) {
661 tBTA_HF_CLIENT evt;
662
663 memset(&evt, 0, sizeof(evt));
664
665 osi_strlcpy(evt.operator_name.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
666 evt.operator_name.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
667
668 evt.operator_name.bd_addr = client_cb->peer_addr;
669 bta_hf_client_app_callback(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
670 }
671
672 /*******************************************************************************
673 *
674 * Function bta_hf_client_clip
675 *
676 * Description Send CLIP event to application.
677 *
678 *
679 * Returns void
680 *
681 ******************************************************************************/
bta_hf_client_clip(tBTA_HF_CLIENT_CB * client_cb,char * number)682 void bta_hf_client_clip(tBTA_HF_CLIENT_CB* client_cb, char* number) {
683 tBTA_HF_CLIENT evt;
684
685 memset(&evt, 0, sizeof(evt));
686
687 osi_strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
688 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
689
690 evt.number.bd_addr = client_cb->peer_addr;
691 bta_hf_client_app_callback(BTA_HF_CLIENT_CLIP_EVT, &evt);
692 }
693
694 /*******************************************************************************
695 *
696 * Function bta_hf_client_ccwa
697 *
698 * Description Send CLIP event to application.
699 *
700 *
701 * Returns void
702 *
703 ******************************************************************************/
bta_hf_client_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * number)704 void bta_hf_client_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* number) {
705 tBTA_HF_CLIENT evt;
706
707 memset(&evt, 0, sizeof(evt));
708
709 osi_strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
710 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
711
712 evt.number.bd_addr = client_cb->peer_addr;
713 bta_hf_client_app_callback(BTA_HF_CLIENT_CCWA_EVT, &evt);
714 }
715
716 /*******************************************************************************
717 *
718 * Function bta_hf_client_at_result
719 *
720 * Description Send AT result event to application.
721 *
722 *
723 * Returns void
724 *
725 ******************************************************************************/
bta_hf_client_at_result(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_RESULT_TYPE type,uint16_t cme)726 void bta_hf_client_at_result(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_AT_RESULT_TYPE type,
727 uint16_t cme) {
728 tBTA_HF_CLIENT evt;
729
730 memset(&evt, 0, sizeof(evt));
731
732 evt.result.type = type;
733 evt.result.cme = cme;
734
735 evt.result.bd_addr = client_cb->peer_addr;
736 bta_hf_client_app_callback(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
737 }
738
739 /*******************************************************************************
740 *
741 * Function bta_hf_client_clcc
742 *
743 * Description Send clcc event to application.
744 *
745 *
746 * Returns void
747 *
748 ******************************************************************************/
bta_hf_client_clcc(tBTA_HF_CLIENT_CB * client_cb,uint32_t idx,bool incoming,uint8_t status,bool mpty,char * number)749 void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx, bool incoming, uint8_t status,
750 bool mpty, char* number) {
751 tBTA_HF_CLIENT evt;
752
753 memset(&evt, 0, sizeof(evt));
754
755 evt.clcc.idx = idx;
756 evt.clcc.inc = incoming;
757 evt.clcc.status = status;
758 evt.clcc.mpty = mpty;
759
760 if (number) {
761 evt.clcc.number_present = true;
762 osi_strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
763 evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
764 }
765
766 evt.clcc.bd_addr = client_cb->peer_addr;
767 bta_hf_client_app_callback(BTA_HF_CLIENT_CLCC_EVT, &evt);
768 }
769
770 /*******************************************************************************
771 *
772 * Function bta_hf_client_cnum
773 *
774 * Description Send cnum event to application.
775 *
776 *
777 * Returns void
778 *
779 ******************************************************************************/
bta_hf_client_cnum(tBTA_HF_CLIENT_CB * client_cb,char * number,uint16_t service)780 void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number, uint16_t service) {
781 tBTA_HF_CLIENT evt = {};
782
783 evt.cnum.service = service;
784 osi_strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
785 evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
786
787 evt.cnum.bd_addr = client_cb->peer_addr;
788 bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
789 }
790
bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB * client_cb,const char * evt_buffer)791 void bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB* client_cb, const char* evt_buffer) {
792 tBTA_HF_CLIENT evt = {};
793
794 osi_strlcpy(evt.unknown.event_string, evt_buffer, BTA_HF_CLIENT_UNKNOWN_EVENT_LEN + 1);
795 evt.unknown.event_string[BTA_HF_CLIENT_UNKNOWN_EVENT_LEN] = '\0';
796
797 evt.unknown.bd_addr = client_cb->peer_addr;
798 bta_hf_client_app_callback(BTA_HF_CLIENT_UNKNOWN_EVT, &evt);
799 }
800
801 /*******************************************************************************
802 *
803 * Function bta_hf_client_binp
804 *
805 * Description Send BINP event to application.
806 *
807 *
808 * Returns void
809 *
810 ******************************************************************************/
bta_hf_client_binp(tBTA_HF_CLIENT_CB * client_cb,char * number)811 void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
812 tBTA_HF_CLIENT evt;
813
814 memset(&evt, 0, sizeof(evt));
815
816 osi_strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
817 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
818
819 evt.number.bd_addr = client_cb->peer_addr;
820 bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
821 }
822
823 /******************************************************************************
824 *
825 * COMMON AT EVENTS PARSING FUNCTIONS
826 *
827 ******************************************************************************/
828
829 /* Check if prefix match and skip spaces if any */
830 #define AT_CHECK_EVENT(buf, event) \
831 do { \
832 if (strncmp("\r\n" event, buf, sizeof("\r\n" event) - 1) != 0) \
833 return buf; \
834 (buf) += sizeof("\r\n" event) - 1; \
835 while (*(buf) == ' ') \
836 (buf)++; \
837 } while (0)
838
839 /* check for <cr><lf> and forward buffer if match */
840 #define AT_CHECK_RN(buf) \
841 do { \
842 if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \
843 log::verbose("missing end <cr><lf>"); \
844 return NULL; \
845 } \
846 (buf) += sizeof("\r\n") - 1; \
847 } while (0)
848
849 /* skip rest of AT string up to <cr> */
850 #define AT_SKIP_REST(buf) \
851 do { \
852 while (*(buf) != '\r' && *(buf) != '\0') \
853 (buf)++; \
854 } while (0)
855
bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB * client_cb,char * buffer)856 static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
857 AT_CHECK_EVENT(buffer, "OK");
858 AT_CHECK_RN(buffer);
859
860 bta_hf_client_handle_ok(client_cb);
861
862 return buffer;
863 }
864
bta_hf_client_parse_error(tBTA_HF_CLIENT_CB * client_cb,char * buffer)865 static char* bta_hf_client_parse_error(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
866 AT_CHECK_EVENT(buffer, "ERROR");
867 AT_CHECK_RN(buffer);
868
869 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
870
871 return buffer;
872 }
873
bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB * client_cb,char * buffer)874 static char* bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
875 AT_CHECK_EVENT(buffer, "RING");
876 AT_CHECK_RN(buffer);
877
878 bta_hf_client_handle_ring(client_cb);
879
880 return buffer;
881 }
882
883 /* generic uint32 parser */
bta_hf_client_parse_uint32(tBTA_HF_CLIENT_CB * client_cb,char * buffer,void (* handler_callback)(tBTA_HF_CLIENT_CB *,uint32_t))884 static char* bta_hf_client_parse_uint32(tBTA_HF_CLIENT_CB* client_cb, char* buffer,
885 void (*handler_callback)(tBTA_HF_CLIENT_CB*, uint32_t)) {
886 uint32_t value;
887 int res;
888 int offset;
889
890 res = sscanf(buffer, "%u%n", &value, &offset);
891 if (res < 1) {
892 return NULL;
893 }
894
895 buffer += offset;
896
897 AT_CHECK_RN(buffer);
898
899 handler_callback(client_cb, value);
900 return buffer;
901 }
902
bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB * client_cb,char * buffer)903 static char* bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
904 AT_CHECK_EVENT(buffer, "+BRSF:");
905
906 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_brsf);
907 }
908
bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB * client_cb,char * buffer)909 static char* bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
910 /* value and its position */
911 uint16_t index = 0;
912 uint32_t value = 0;
913
914 int offset;
915 int res;
916
917 while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
918 /* decides if its valid index and value, if yes stores it */
919 bta_hf_client_handle_cind_value(client_cb, index, value);
920
921 buffer += offset;
922
923 /* check if more values are present */
924 if (*buffer != ',') {
925 break;
926 }
927
928 index++;
929 buffer++;
930 }
931
932 if (res > 0) {
933 AT_CHECK_RN(buffer);
934 return buffer;
935 }
936
937 return NULL;
938 }
939
bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB * client_cb,char * buffer)940 static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
941 int offset = 0;
942 char name[129];
943 uint32_t min, max;
944 uint32_t index = 0;
945 int res;
946
947 while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2) {
948 bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index);
949 if (offset == 0) {
950 log::error("Format Error {}", buffer);
951 return NULL;
952 }
953
954 buffer += offset;
955 index++;
956
957 if (*buffer != ',') {
958 break;
959 }
960
961 buffer++;
962 }
963
964 if (res > 2) {
965 AT_CHECK_RN(buffer);
966 return buffer;
967 }
968
969 return NULL;
970 }
971
bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB * client_cb,char * buffer)972 static char* bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
973 AT_CHECK_EVENT(buffer, "+CIND:");
974
975 if (*buffer == '(') {
976 return bta_hf_client_parse_cind_list(client_cb, buffer);
977 }
978
979 return bta_hf_client_parse_cind_values(client_cb, buffer);
980 }
981
bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB * client_cb,char * buffer)982 static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
983 AT_CHECK_EVENT(buffer, "+CHLD:");
984
985 if (*buffer != '(') {
986 return NULL;
987 }
988
989 buffer++;
990
991 while (*buffer != '\0') {
992 if (strncmp("0", buffer, 1) == 0) {
993 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL);
994 buffer++;
995 } else if (strncmp("1x", buffer, 2) == 0) {
996 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_X);
997 buffer += 2;
998 } else if (strncmp("1", buffer, 1) == 0) {
999 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_ACC);
1000 buffer++;
1001 } else if (strncmp("2x", buffer, 2) == 0) {
1002 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_PRIV_X);
1003 buffer += 2;
1004 } else if (strncmp("2", buffer, 1) == 0) {
1005 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_HOLD_ACC);
1006 buffer++;
1007 } else if (strncmp("3", buffer, 1) == 0) {
1008 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE);
1009 buffer++;
1010 } else if (strncmp("4", buffer, 1) == 0) {
1011 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE_DETACH);
1012 buffer++;
1013 } else {
1014 return NULL;
1015 }
1016
1017 if (*buffer == ',') {
1018 buffer++;
1019 continue;
1020 }
1021
1022 if (*buffer == ')') {
1023 buffer++;
1024 break;
1025 }
1026
1027 return NULL;
1028 }
1029
1030 AT_CHECK_RN(buffer);
1031
1032 return buffer;
1033 }
1034
bta_hf_client_parse_bind(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1035 static char* bta_hf_client_parse_bind(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1036 AT_CHECK_EVENT(buffer, "+BIND:");
1037
1038 uint8_t mode = BTA_HF_CLIENT_BIND_PARSE_READ_ENABLED_IND;
1039
1040 int idx = -1;
1041
1042 while (*buffer != 0) {
1043 switch (*buffer) {
1044 case '(':
1045 mode = BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND;
1046 break;
1047 case ')':
1048 break;
1049 case '0':
1050 case '1':
1051 case '2':
1052 if (mode == BTA_HF_CLIENT_BIND_PARSE_READ_SUPPOETED_IND) {
1053 // +BIND: (id0, id1, ...)
1054 bta_hf_client_handle_bind_read_supported_ind(client_cb, (*buffer - '0'));
1055 } else if (idx == -1) {
1056 // +BIND: [id]...
1057 idx = *buffer - '0';
1058 } else {
1059 // +BIND: ...[status]
1060 bta_hf_client_handle_bind_read_enabled_ind(client_cb, idx, *buffer - '0');
1061 }
1062 break;
1063 default:
1064 break;
1065 }
1066 buffer++;
1067 }
1068
1069 AT_CHECK_RN(buffer);
1070
1071 return buffer;
1072 }
1073
bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1074 static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1075 uint32_t index, value;
1076 int res;
1077 int offset = 0;
1078
1079 AT_CHECK_EVENT(buffer, "+CIEV:");
1080
1081 res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
1082 if (res < 2) {
1083 return NULL;
1084 }
1085
1086 if (offset == 0) {
1087 log::error("Format Error {}", buffer);
1088 return NULL;
1089 }
1090
1091 buffer += offset;
1092
1093 AT_CHECK_RN(buffer);
1094
1095 bta_hf_client_handle_ciev(client_cb, index, value);
1096 return buffer;
1097 }
1098
bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1099 static char* bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1100 AT_CHECK_EVENT(buffer, "+BCS:");
1101
1102 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_bcs);
1103 }
1104
bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1105 static char* bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1106 AT_CHECK_EVENT(buffer, "+BSIR:");
1107
1108 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_bsir);
1109 }
1110
bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1111 static char* bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1112 AT_CHECK_EVENT(buffer, "+CME ERROR:");
1113
1114 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_cmeerror);
1115 }
1116
bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1117 static char* bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1118 AT_CHECK_EVENT(buffer, "+VGM:");
1119
1120 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_vgm);
1121 }
1122
bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1123 static char* bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1124 AT_CHECK_EVENT(buffer, "+VGM=");
1125
1126 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_vgm);
1127 }
1128
bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1129 static char* bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1130 AT_CHECK_EVENT(buffer, "+VGS:");
1131
1132 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_vgs);
1133 }
1134
bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1135 static char* bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1136 AT_CHECK_EVENT(buffer, "+VGS=");
1137
1138 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_vgs);
1139 }
1140
bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1141 static char* bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1142 AT_CHECK_EVENT(buffer, "+BVRA:");
1143
1144 return bta_hf_client_parse_uint32(client_cb, buffer, bta_hf_client_handle_bvra);
1145 }
1146
bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1147 static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1148 /* spec forces 32 chars, plus \0 here */
1149 char number[33];
1150 uint32_t type = 0;
1151 int res;
1152 int offset = 0;
1153
1154 AT_CHECK_EVENT(buffer, "+CLIP:");
1155
1156 /* there might be something more after %lu but HFP doesn't care */
1157 res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1158 if (res < 2) {
1159 return NULL;
1160 }
1161
1162 if (offset == 0) {
1163 log::error("Format Error {}", buffer);
1164 return NULL;
1165 }
1166
1167 buffer += offset;
1168
1169 AT_SKIP_REST(buffer);
1170
1171 AT_CHECK_RN(buffer);
1172
1173 bta_hf_client_handle_clip(client_cb, number, type);
1174 return buffer;
1175 }
1176
1177 /* in HFP context there is no difference between ccwa and clip */
bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1178 static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1179 /* ac to spec 32 chars max, plus \0 here */
1180 char number[33];
1181 uint32_t type = 0;
1182 int res;
1183 int offset = 0;
1184
1185 AT_CHECK_EVENT(buffer, "+CCWA:");
1186
1187 /* there might be something more after %lu but HFP doesn't care */
1188 res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1189 if (res < 2) {
1190 return NULL;
1191 }
1192
1193 if (offset == 0) {
1194 log::error("Format Error {}", buffer);
1195 return NULL;
1196 }
1197
1198 buffer += offset;
1199
1200 AT_SKIP_REST(buffer);
1201
1202 AT_CHECK_RN(buffer);
1203
1204 bta_hf_client_handle_ccwa(client_cb, number, type);
1205 return buffer;
1206 }
1207
bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1208 static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1209 uint8_t mode;
1210 /* spec forces 16 chars max, plus \0 here */
1211 char opstr[17];
1212 int res;
1213 int offset = 0;
1214
1215 AT_CHECK_EVENT(buffer, "+COPS:");
1216
1217 /* TODO: Not sure if operator string actually can contain escaped " char
1218 * inside */
1219 res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
1220 if (res < 2) {
1221 return NULL;
1222 }
1223 /* Abort in case offset not set because of format error */
1224 if (offset == 0) {
1225 log::error("Format Error {}", buffer);
1226 return NULL;
1227 }
1228
1229 buffer += offset;
1230
1231 AT_SKIP_REST(buffer);
1232
1233 AT_CHECK_RN(buffer);
1234
1235 bta_hf_client_handle_cops(client_cb, opstr, mode);
1236 // check for OK Response in end
1237 AT_CHECK_EVENT(buffer, "OK");
1238 AT_CHECK_RN(buffer);
1239
1240 bta_hf_client_handle_ok(client_cb);
1241
1242 return buffer;
1243 }
1244
bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1245 static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1246 /* HFP only supports phone number as BINP data */
1247 /* phone number is 32 chars plus one for \0*/
1248 char numstr[33];
1249 int res;
1250 int offset = 0;
1251
1252 AT_CHECK_EVENT(buffer, "+BINP:");
1253
1254 res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
1255 if (res < 1) {
1256 return NULL;
1257 }
1258
1259 /* Abort in case offset not set because of format error */
1260 if (offset == 0) {
1261 log::error("Format Error {}", buffer);
1262 return NULL;
1263 }
1264
1265 buffer += offset;
1266
1267 /* some phones might sent type as well, just skip it */
1268 AT_SKIP_REST(buffer);
1269
1270 AT_CHECK_RN(buffer);
1271
1272 bta_hf_client_handle_binp(client_cb, numstr);
1273
1274 // check for OK response in end
1275 AT_CHECK_EVENT(buffer, "OK");
1276 AT_CHECK_RN(buffer);
1277
1278 bta_hf_client_handle_ok(client_cb);
1279
1280 return buffer;
1281 }
1282
bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1283 static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1284 uint16_t idx, dir, status, mode, mpty;
1285 char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1286 uint16_t type = 0;
1287 int res;
1288 int offset = 0;
1289
1290 AT_CHECK_EVENT(buffer, "+CLCC:");
1291
1292 res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode, &mpty, &offset);
1293 if (res < 5) {
1294 return NULL;
1295 }
1296
1297 /* Abort in case offset not set because of format error */
1298 if (offset == 0) {
1299 log::error("Format Error {}", buffer);
1300 return NULL;
1301 }
1302
1303 buffer += offset;
1304 offset = 0;
1305
1306 /* check optional part */
1307 if (*buffer == ',') {
1308 int res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
1309 if (res2 < 0) {
1310 return NULL;
1311 }
1312
1313 if (res2 == 0) {
1314 res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
1315 if (res2 < 0) {
1316 return NULL;
1317 }
1318
1319 /* numstr is not matched in second attempt, correct this */
1320 res2++;
1321 numstr[0] = '\0';
1322 }
1323
1324 if (res2 >= 2) {
1325 res += res2;
1326 /* Abort in case offset not set because of format error */
1327 if (offset == 0) {
1328 log::error("Format Error {}", buffer);
1329 return NULL;
1330 }
1331
1332 buffer += offset;
1333 }
1334 }
1335
1336 /* Skip any remaing param,as they are not defined by BT HFP spec */
1337 AT_SKIP_REST(buffer);
1338 AT_CHECK_RN(buffer);
1339
1340 if (res > 6) {
1341 /* we also have last two optional parameters */
1342 bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, numstr, type);
1343 } else {
1344 /* we didn't get the last two parameters */
1345 bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, NULL, 0);
1346 }
1347
1348 // check for OK response in end
1349 AT_CHECK_EVENT(buffer, "OK");
1350 AT_CHECK_RN(buffer);
1351
1352 bta_hf_client_handle_ok(client_cb);
1353 return buffer;
1354 }
1355
bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1356 static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1357 char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1358 uint16_t type;
1359 uint16_t service = 0; /* 0 in case this optional parameter is not being sent */
1360 int res;
1361 int offset = 0;
1362
1363 AT_CHECK_EVENT(buffer, "+CNUM:");
1364
1365 res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service, &offset);
1366 if (res < 0) {
1367 return NULL;
1368 }
1369
1370 if (res == 0) {
1371 res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
1372 if (res < 0) {
1373 return NULL;
1374 }
1375
1376 /* numstr is not matched in second attempt, correct this */
1377 res++;
1378 numstr[0] = '\0';
1379 }
1380
1381 if (res < 3) {
1382 return NULL;
1383 }
1384
1385 /* Abort in case offset not set because of format error */
1386 if (offset == 0) {
1387 log::error("Format Error {}", buffer);
1388 return NULL;
1389 }
1390
1391 buffer += offset;
1392
1393 AT_CHECK_RN(buffer);
1394
1395 /* service is optional */
1396 if (res == 2) {
1397 bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1398 return buffer;
1399 }
1400
1401 if (service != 4 && service != 5) {
1402 return NULL;
1403 }
1404
1405 bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1406
1407 // check for OK response in end
1408 AT_CHECK_EVENT(buffer, "OK");
1409 AT_CHECK_RN(buffer);
1410
1411 bta_hf_client_handle_ok(client_cb);
1412 return buffer;
1413 }
1414
bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1415 static char* bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1416 uint16_t code = 0;
1417 int res;
1418 int offset;
1419
1420 AT_CHECK_EVENT(buffer, "+BTRH:");
1421
1422 res = sscanf(buffer, "%hu%n", &code, &offset);
1423 if (res < 1) {
1424 return NULL;
1425 }
1426
1427 buffer += offset;
1428
1429 AT_CHECK_RN(buffer);
1430
1431 bta_hf_client_handle_btrh(client_cb, code);
1432 return buffer;
1433 }
1434
bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1435 static char* bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1436 AT_CHECK_EVENT(buffer, "BUSY");
1437 AT_CHECK_RN(buffer);
1438
1439 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
1440
1441 return buffer;
1442 }
1443
bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1444 static char* bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1445 AT_CHECK_EVENT(buffer, "DELAYED");
1446 AT_CHECK_RN(buffer);
1447
1448 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
1449
1450 return buffer;
1451 }
1452
bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1453 static char* bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1454 AT_CHECK_EVENT(buffer, "NO CARRIER");
1455 AT_CHECK_RN(buffer);
1456
1457 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
1458
1459 return buffer;
1460 }
1461
bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1462 static char* bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1463 AT_CHECK_EVENT(buffer, "NO ANSWER");
1464 AT_CHECK_RN(buffer);
1465
1466 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
1467
1468 return buffer;
1469 }
1470
bta_hf_client_parse_rejectlisted(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1471 static char* bta_hf_client_parse_rejectlisted(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1472 AT_CHECK_EVENT(buffer, "REJECTLISTED");
1473 AT_CHECK_RN(buffer);
1474
1475 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_REJECTLISTED, 0);
1476
1477 return buffer;
1478 }
1479
bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB *,char * buffer)1480 static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* /*client_cb*/, char* buffer) {
1481 char* start;
1482 char* tmp;
1483
1484 tmp = strstr(buffer, "\r\n");
1485 if (tmp == NULL) {
1486 return NULL;
1487 }
1488
1489 buffer += 2;
1490 start = buffer;
1491
1492 tmp = strstr(buffer, "\r\n");
1493 if (tmp == NULL) {
1494 return NULL;
1495 }
1496
1497 buffer = tmp + 2;
1498
1499 log::verbose("{:.{}}", start, (int)(buffer - start - 2));
1500
1501 return buffer;
1502 }
1503
bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1504 static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb, char* buffer) {
1505 char* start = strstr(buffer, "\r\n");
1506 if (start == NULL) {
1507 return NULL;
1508 }
1509 start += sizeof("\r\n") - 1;
1510
1511 char* end = strstr(start, "\r\n");
1512 if (end == NULL) {
1513 return NULL;
1514 }
1515
1516 int evt_size = end - start + 1;
1517
1518 char tmp_buf[BTA_HF_CLIENT_UNKNOWN_EVENT_LEN];
1519 if (evt_size < BTA_HF_CLIENT_UNKNOWN_EVENT_LEN) {
1520 osi_strlcpy(tmp_buf, start, evt_size);
1521 bta_hf_client_unknown_response(client_cb, tmp_buf);
1522 AT_CHECK_RN(end);
1523 } else {
1524 log::error("exceed event buffer size. ({}, {})", evt_size, BTA_HF_CLIENT_UNKNOWN_EVENT_LEN);
1525 }
1526
1527 log::verbose("{}", buffer);
1528
1529 return end;
1530 }
1531
1532 /******************************************************************************
1533 * SUPPORTED EVENT MESSAGES
1534 ******************************************************************************/
1535
1536 /* returned values are as follow:
1537 * != NULL && != buf : match and parsed ok
1538 * == NULL : match but parse failed
1539 * != NULL && == buf : no match
1540 */
1541 typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
1542
1543 static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
1544 bta_hf_client_parse_ok, bta_hf_client_parse_error,
1545 bta_hf_client_parse_ring, bta_hf_client_parse_brsf,
1546 bta_hf_client_parse_cind, bta_hf_client_parse_ciev,
1547 bta_hf_client_parse_chld, bta_hf_client_parse_bcs,
1548 bta_hf_client_parse_bsir, bta_hf_client_parse_cmeerror,
1549 bta_hf_client_parse_vgm, bta_hf_client_parse_vgme,
1550 bta_hf_client_parse_vgs, bta_hf_client_parse_vgse,
1551 bta_hf_client_parse_bvra, bta_hf_client_parse_clip,
1552 bta_hf_client_parse_ccwa, bta_hf_client_parse_cops,
1553 bta_hf_client_parse_binp, bta_hf_client_parse_clcc,
1554 bta_hf_client_parse_cnum, bta_hf_client_parse_btrh,
1555 bta_hf_client_parse_bind, bta_hf_client_parse_busy,
1556 bta_hf_client_parse_delayed, bta_hf_client_parse_no_carrier,
1557 bta_hf_client_parse_no_answer, bta_hf_client_parse_rejectlisted,
1558 bta_hf_client_process_unknown};
1559
1560 /* calculate supported event list length */
1561 static const uint16_t bta_hf_client_parser_cb_count =
1562 sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
1563
1564 #ifdef BTA_HF_CLIENT_AT_DUMP
bta_hf_client_dump_at(tBTA_HF_CLIENT_CB * client_cb)1565 static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
1566 char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
1567 char *p1, *p2;
1568
1569 p1 = client_cb->at_cb.buf;
1570 p2 = dump;
1571
1572 while (*p1 != '\0') {
1573 if (*p1 == '\r') {
1574 strncpy(p2, "<cr>", 4);
1575 p2 += 4;
1576 } else if (*p1 == '\n') {
1577 strncpy(p2, "<lf>", 4);
1578 p2 += 4;
1579 } else {
1580 *p2 = *p1;
1581 p2++;
1582 }
1583 p1++;
1584 }
1585
1586 *p2 = '\0';
1587
1588 log::verbose("{}", dump);
1589 }
1590 #endif
1591
bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB * client_cb)1592 static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
1593 char* buf = client_cb->at_cb.buf;
1594
1595 log::verbose("");
1596
1597 #ifdef BTA_HF_CLIENT_AT_DUMP
1598 bta_hf_client_dump_at(client_cb);
1599 #endif
1600
1601 while (*buf != '\0') {
1602 int i;
1603 char* tmp = NULL;
1604
1605 for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
1606 tmp = bta_hf_client_parser_cb[i](client_cb, buf);
1607 if (tmp == NULL) {
1608 log::error("HFPCient: AT event/reply parsing failed, skipping");
1609 tmp = bta_hf_client_skip_unknown(client_cb, buf);
1610 break;
1611 }
1612
1613 /* matched or unknown skipped, if unknown failed tmp is NULL so
1614 this is also handled */
1615 if (tmp != buf) {
1616 buf = tmp;
1617 break;
1618 }
1619 }
1620
1621 /* could not skip unknown (received garbage?)... disconnect */
1622 if (tmp == NULL) {
1623 log::error("HFPCient: could not skip unknown AT event, disconnecting");
1624 bta_hf_client_at_reset(client_cb);
1625
1626 tBTA_HF_CLIENT_DATA msg = {};
1627 msg.hdr.layer_specific = client_cb->handle;
1628 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1629 return;
1630 }
1631
1632 buf = tmp;
1633 }
1634 }
1635
bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB * client_cb)1636 static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
1637 bool ret = false;
1638 tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
1639
1640 if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
1641 if (at_cb->buf[at_cb->offset - 2] == '\r' && at_cb->buf[at_cb->offset - 1] == '\n') {
1642 ret = true;
1643 }
1644 }
1645
1646 log::verbose("{}", ret);
1647
1648 return ret;
1649 }
1650
bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB * client_cb)1651 static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
1652 memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
1653 client_cb->at_cb.offset = 0;
1654 }
1655
1656 /******************************************************************************
1657 *
1658 * MAIN PARSING FUNCTION
1659 *
1660 *
1661 ******************************************************************************/
bta_hf_client_at_parse(tBTA_HF_CLIENT_CB * client_cb,char * buf,unsigned int len)1662 void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf, unsigned int len) {
1663 log::verbose("offset: {} len: {}", client_cb->at_cb.offset, len);
1664
1665 if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
1666 char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
1667 unsigned int tmp = client_cb->at_cb.offset;
1668 unsigned int space_left = BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
1669
1670 log::verbose("overrun, trying to recover");
1671
1672 /* fill up parser buffer */
1673 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
1674 len -= space_left;
1675 buf += space_left;
1676 client_cb->at_cb.offset += space_left;
1677
1678 /* find end of last complete command before proceeding */
1679 while (!bta_hf_client_check_at_complete(client_cb)) {
1680 if (client_cb->at_cb.offset == 0) {
1681 log::error("HFPClient: AT parser buffer overrun, disconnecting");
1682
1683 bta_hf_client_at_reset(client_cb);
1684
1685 tBTA_HF_CLIENT_DATA msg = {};
1686 msg.hdr.layer_specific = client_cb->handle;
1687 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1688 return;
1689 }
1690
1691 client_cb->at_cb.offset--;
1692 }
1693
1694 /* cut buffer to complete AT event and keep cut data */
1695 tmp += space_left - client_cb->at_cb.offset;
1696 memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
1697 client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
1698
1699 /* parse */
1700 bta_hf_client_at_parse_start(client_cb);
1701 bta_hf_client_at_clear_buf(client_cb);
1702
1703 /* recover cut data */
1704 memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
1705 client_cb->at_cb.offset += tmp;
1706 }
1707
1708 /* prevent buffer overflow in cases where LEN exceeds available buffer space
1709 */
1710 if (len > BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset) {
1711 return;
1712 }
1713
1714 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
1715 client_cb->at_cb.offset += len;
1716
1717 /* If last event is complete, parsing can be started */
1718 if (bta_hf_client_check_at_complete(client_cb)) {
1719 bta_hf_client_at_parse_start(client_cb);
1720 bta_hf_client_at_clear_buf(client_cb);
1721 }
1722 }
1723
bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_FEAT features)1724 void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb, tBTA_HF_CLIENT_FEAT features) {
1725 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1726 int at_len;
1727
1728 log::verbose("");
1729
1730 at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
1731 if (at_len < 0) {
1732 log::error("AT command Framing error");
1733 return;
1734 }
1735
1736 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
1737 }
1738
bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB * client_cb)1739 void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
1740 const char* buf;
1741
1742 log::verbose("");
1743
1744 if (bta_hf_client_cb_arr.is_support_lc3) {
1745 buf = "AT+BAC=1,2,3\r";
1746 } else {
1747 buf = "AT+BAC=1,2\r";
1748 }
1749
1750 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
1751 }
1752
bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)1753 void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
1754 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1755 int at_len;
1756
1757 log::verbose("");
1758
1759 at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
1760 if (at_len < 0) {
1761 log::error("AT command Framing error");
1762 return;
1763 }
1764
1765 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
1766 }
1767
bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB * client_cb,bool status)1768 void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
1769 const char* buf;
1770 tBTA_HF_CLIENT_AT_CMD cmd;
1771
1772 log::verbose("");
1773
1774 if (status) {
1775 buf = "AT+CIND?\r";
1776 cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
1777 } else {
1778 buf = "AT+CIND=?\r";
1779 cmd = BTA_HF_CLIENT_AT_CIND;
1780 }
1781
1782 bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
1783 }
1784
bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB * client_cb,bool activate)1785 void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1786 const char* buf;
1787
1788 log::verbose("");
1789
1790 if (activate) {
1791 buf = "AT+CMER=3,0,0,1\r";
1792 } else {
1793 buf = "AT+CMER=3,0,0,0\r";
1794 }
1795
1796 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
1797 }
1798
bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB * client_cb,char cmd,uint32_t idx)1799 void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd, uint32_t idx) {
1800 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1801 int at_len;
1802
1803 log::verbose("");
1804
1805 if (idx > 0) {
1806 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
1807 } else {
1808 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
1809 }
1810
1811 if (at_len < 0) {
1812 log::error("AT command Framing error");
1813 return;
1814 }
1815
1816 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
1817 }
1818
bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB * client_cb,int step)1819 void bta_hf_client_send_at_bind(tBTA_HF_CLIENT_CB* client_cb, int step) {
1820 std::string buf;
1821 tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;
1822
1823 log::verbose("");
1824
1825 switch (step) {
1826 case 0: // List HF supported indicators
1827 if (osi_property_get_bool(kPropertyEnhancedDrivingIndicatorEnabled, false)) {
1828 buf = "AT+BIND=1,2\r";
1829 } else {
1830 buf = "AT+BIND=2\r";
1831 }
1832 cmd = BTA_HF_CLIENT_AT_BIND_SET_IND;
1833 break;
1834 case 1: // Read AG supported indicators
1835 buf = "AT+BIND=?\r";
1836 cmd = BTA_HF_CLIENT_AT_BIND_READ_SUPPORTED_IND;
1837 break;
1838 case 2: // Read AG enabled/disabled status of indicators
1839 buf = "AT+BIND?\r";
1840 cmd = BTA_HF_CLIENT_AT_BIND_READ_ENABLED_IND;
1841 break;
1842 default:
1843 break;
1844 }
1845 bta_hf_client_send_at(client_cb, cmd, buf.c_str(), buf.size());
1846 }
1847
bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB * client_cb,int indicator_id,int indicator_value)1848 void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id,
1849 int indicator_value) {
1850 char buf[32];
1851 tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIEV;
1852
1853 if ((client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) == 0) {
1854 log::error("peer does not support HF Indicators");
1855 return;
1856 }
1857
1858 if (client_cb->enabled_hf_indicators.count(indicator_id) <= 0) {
1859 log::error("HF indicators {} is disabled", indicator_id);
1860 return;
1861 }
1862
1863 log::verbose("");
1864
1865 int len = sprintf(buf, "AT+BIEV=%d,%d\r", indicator_id, indicator_value);
1866
1867 bta_hf_client_send_at(client_cb, cmd, buf, len);
1868 }
1869
bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB * client_cb,bool activate)1870 void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1871 const char* buf;
1872
1873 log::verbose("");
1874
1875 if (activate) {
1876 buf = "AT+CLIP=1\r";
1877 } else {
1878 buf = "AT+CLIP=0\r";
1879 }
1880
1881 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
1882 }
1883
bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB * client_cb,bool activate)1884 void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1885 const char* buf;
1886
1887 log::verbose("");
1888
1889 if (activate) {
1890 buf = "AT+CCWA=1\r";
1891 } else {
1892 buf = "AT+CCWA=0\r";
1893 }
1894
1895 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
1896 }
1897
bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB * client_cb,bool activate)1898 void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1899 const char* buf;
1900
1901 log::verbose("");
1902
1903 if (activate) {
1904 buf = "AT+CMEE=1\r";
1905 } else {
1906 buf = "AT+CMEE=0\r";
1907 }
1908
1909 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
1910 }
1911
bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB * client_cb,bool query)1912 void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
1913 const char* buf;
1914
1915 log::verbose("");
1916
1917 if (query) {
1918 buf = "AT+COPS?\r";
1919 } else {
1920 buf = "AT+COPS=3,0\r";
1921 }
1922
1923 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
1924 }
1925
bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB * client_cb)1926 void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
1927 const char* buf;
1928
1929 log::verbose("");
1930
1931 buf = "AT+CLCC\r";
1932
1933 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
1934 }
1935
bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB * client_cb,bool enable)1936 void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
1937 const char* buf;
1938
1939 log::verbose("");
1940
1941 if (enable) {
1942 buf = "AT+BVRA=1\r";
1943 } else {
1944 buf = "AT+BVRA=0\r";
1945 }
1946
1947 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
1948 }
1949
bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1950 void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1951 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1952 int at_len;
1953
1954 log::verbose("");
1955
1956 at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
1957 if (at_len < 0) {
1958 log::error("AT command Framing error");
1959 return;
1960 }
1961
1962 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
1963 }
1964
bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1965 void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1966 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1967 int at_len;
1968
1969 log::verbose("");
1970
1971 at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
1972 if (at_len < 0) {
1973 log::error("AT command Framing error");
1974 return;
1975 }
1976
1977 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
1978 }
1979
bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB * client_cb,char * number,uint32_t memory)1980 void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number, uint32_t memory) {
1981 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1982 int at_len;
1983
1984 log::verbose("");
1985
1986 if (number[0] != '\0') {
1987 at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
1988 } else {
1989 at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
1990 }
1991
1992 if (at_len < 0) {
1993 log::error("error preparing ATD command");
1994 return;
1995 }
1996
1997 at_len = MIN((size_t)at_len, sizeof(buf));
1998
1999 if (at_len < 0) {
2000 log::error("AT command Framing error");
2001 return;
2002 }
2003 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
2004 }
2005
bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB * client_cb)2006 void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
2007 const char* buf;
2008
2009 log::verbose("");
2010
2011 buf = "AT+BLDN\r";
2012
2013 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
2014 }
2015
bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB * client_cb)2016 void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
2017 const char* buf;
2018
2019 log::verbose("");
2020
2021 buf = "ATA\r";
2022
2023 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
2024 }
2025
bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB * client_cb)2026 void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
2027 const char* buf;
2028
2029 log::verbose("");
2030
2031 buf = "AT+CHUP\r";
2032
2033 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
2034 }
2035
bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB * client_cb,bool query,uint32_t val)2036 void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query, uint32_t val) {
2037 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2038 int at_len;
2039
2040 log::verbose("");
2041
2042 if (query) {
2043 at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
2044 } else {
2045 at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
2046 }
2047
2048 if (at_len < 0) {
2049 log::error("AT command Framing error");
2050 return;
2051 }
2052
2053 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
2054 }
2055
bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB * client_cb,char code)2056 void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
2057 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2058 int at_len;
2059
2060 log::verbose("");
2061
2062 at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
2063
2064 if (at_len < 0) {
2065 log::error("AT command Framing error");
2066 return;
2067 }
2068
2069 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
2070 }
2071
bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB * client_cb)2072 void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
2073 const char* buf;
2074
2075 log::verbose("");
2076
2077 buf = "AT+BCC\r";
2078
2079 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
2080 }
2081
bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB * client_cb)2082 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
2083 const char* buf;
2084
2085 log::verbose("");
2086
2087 buf = "AT+CNUM\r";
2088
2089 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
2090 }
2091
bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB * client_cb)2092 void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
2093 const char* buf;
2094
2095 log::verbose("");
2096
2097 if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
2098 log::error("Remote does not support NREC.");
2099 return;
2100 }
2101
2102 buf = "AT+NREC=0\r";
2103
2104 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
2105 }
2106
bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB * client_cb,uint32_t action)2107 void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
2108 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2109 int at_len;
2110
2111 log::verbose("");
2112
2113 at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
2114
2115 if (at_len < 0) {
2116 log::error("AT command Framing error");
2117 return;
2118 }
2119
2120 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
2121 }
2122
bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB * client_cb)2123 void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
2124 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2125 int at_len;
2126 int i;
2127
2128 log::verbose("");
2129 if (client_cb->peer_version < HFP_VERSION_1_6) {
2130 log::verbose("Remote does not Support AT+BIA");
2131 return;
2132 }
2133
2134 at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
2135
2136 const int32_t position =
2137 osi_property_get_int32("bluetooth.headset_client.disable_indicator.position", -1);
2138
2139 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2140 int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
2141
2142 /* If this value matches the position of SIGNAL in the indicators array,
2143 * then hardcode disable signal strength indicators.
2144 * indicator_lookup[i] points to the position in the
2145 * bta_hf_client_indicators array defined at the top of this file */
2146 if (client_cb->at_cb.indicator_lookup[i] == position) {
2147 sup = 0;
2148 }
2149
2150 at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
2151 }
2152
2153 buf[at_len - 1] = '\r';
2154
2155 if (at_len < 0) {
2156 log::error("AT command Framing error");
2157 return;
2158 }
2159
2160 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
2161 }
2162
bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB * client_cb,const char * str)2163 void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb, const char* str) {
2164 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2165
2166 log::verbose("");
2167
2168 int at_len = snprintf(buf, sizeof(buf), "AT%s", str);
2169
2170 if (at_len < 1) {
2171 log::error("AT command Framing error");
2172 return;
2173 }
2174
2175 buf[at_len - 1] = '\r';
2176
2177 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VENDOR_SPECIFIC, buf, at_len);
2178 }
2179
bta_hf_client_send_at_android(tBTA_HF_CLIENT_CB * client_cb,const char * str)2180 void bta_hf_client_send_at_android(tBTA_HF_CLIENT_CB* client_cb, const char* str) {
2181 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2182 int at_len;
2183
2184 log::verbose("");
2185
2186 at_len = snprintf(buf, sizeof(buf), "AT%s\r", str);
2187 if (at_len < 0) {
2188 log::error("AT command Framing error");
2189 return;
2190 }
2191
2192 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ANDROID, buf, at_len);
2193 }
2194
bta_hf_client_at_init(tBTA_HF_CLIENT_CB * client_cb)2195 void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
2196 alarm_free(client_cb->at_cb.resp_timer);
2197 alarm_free(client_cb->at_cb.hold_timer);
2198 memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
2199 client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
2200 client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
2201 bta_hf_client_at_reset(client_cb);
2202 }
2203
bta_hf_client_at_reset(tBTA_HF_CLIENT_CB * client_cb)2204 void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
2205 int i;
2206
2207 bta_hf_client_stop_at_resp_timer(client_cb);
2208 bta_hf_client_stop_at_hold_timer(client_cb);
2209
2210 bta_hf_client_clear_queued_at(client_cb);
2211
2212 bta_hf_client_at_clear_buf(client_cb);
2213
2214 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2215 client_cb->at_cb.indicator_lookup[i] = -1;
2216 }
2217
2218 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
2219 }
2220
bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA * p_data)2221 void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
2222 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
2223 if (!client_cb) {
2224 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
2225 return;
2226 }
2227
2228 tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
2229 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2230
2231 log::verbose("at cmd: {}", p_val->uint8_val);
2232 switch (p_val->uint8_val) {
2233 case BTA_HF_CLIENT_AT_CMD_VTS:
2234 bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
2235 break;
2236 case BTA_HF_CLIENT_AT_CMD_BTRH:
2237 bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
2238 break;
2239 case BTA_HF_CLIENT_AT_CMD_CHUP:
2240 bta_hf_client_send_at_chup(client_cb);
2241 break;
2242 case BTA_HF_CLIENT_AT_CMD_CHLD:
2243 /* expects ascii code for command */
2244 bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1, p_val->uint32_val2);
2245 break;
2246 case BTA_HF_CLIENT_AT_CMD_BIEV:
2247 /* expects ascii code for command */
2248 bta_hf_client_send_at_biev(client_cb, p_val->uint32_val1, p_val->uint32_val2);
2249 break;
2250 case BTA_HF_CLIENT_AT_CMD_BCC:
2251 bta_hf_client_send_at_bcc(client_cb);
2252 break;
2253 case BTA_HF_CLIENT_AT_CMD_CNUM:
2254 bta_hf_client_send_at_cnum(client_cb);
2255 break;
2256 case BTA_HF_CLIENT_AT_CMD_ATA:
2257 bta_hf_client_send_at_ata(client_cb);
2258 break;
2259 case BTA_HF_CLIENT_AT_CMD_COPS:
2260 bta_hf_client_send_at_cops(client_cb, true);
2261 break;
2262 case BTA_HF_CLIENT_AT_CMD_ATD:
2263 bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
2264 break;
2265 case BTA_HF_CLIENT_AT_CMD_VGM:
2266 bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
2267 break;
2268 case BTA_HF_CLIENT_AT_CMD_VGS:
2269 bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
2270 break;
2271 case BTA_HF_CLIENT_AT_CMD_BVRA:
2272 bta_hf_client_send_at_bvra(client_cb, p_val->uint32_val1 == 0 ? false : true);
2273 break;
2274 case BTA_HF_CLIENT_AT_CMD_CLCC:
2275 bta_hf_client_send_at_clcc(client_cb);
2276 break;
2277 case BTA_HF_CLIENT_AT_CMD_BINP:
2278 bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
2279 break;
2280 case BTA_HF_CLIENT_AT_CMD_BLDN:
2281 bta_hf_client_send_at_bldn(client_cb);
2282 break;
2283 case BTA_HF_CLIENT_AT_CMD_NREC:
2284 bta_hf_client_send_at_nrec(client_cb);
2285 break;
2286 case BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD:
2287 bta_hf_client_send_at_vendor_specific_cmd(client_cb, p_val->str);
2288 break;
2289 case BTA_HF_CLIENT_AT_CMD_ANDROID:
2290 bta_hf_client_send_at_android(client_cb, p_val->str);
2291 break;
2292 default:
2293 log::error("Default case");
2294 snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN, "Cmd %d 1st arg %u 2nd arg %u string arg %s",
2295 p_val->uint8_val, p_val->uint32_val1, p_val->uint32_val2, p_val->str);
2296 log::error("AT buffer: {}", buf);
2297 break;
2298 }
2299 }
2300