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