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