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