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("%s: timed out waiting for AT+CNUM response; spoofing OK.",
147 __func__);
148 bta_hf_client_handle_ok(client_cb);
149 } else {
150 APPL_TRACE_ERROR("HFPClient: AT response timeout, disconnecting");
151
152 tBTA_HF_CLIENT_DATA msg;
153 msg.hdr.layer_specific = client_cb->handle;
154 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
155 }
156 }
157
bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB * client_cb)158 static void bta_hf_client_start_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
159 alarm_set_on_mloop(client_cb->at_cb.resp_timer, BTA_HF_CLIENT_AT_TIMEOUT,
160 bta_hf_client_at_resp_timer_cback, (void*)client_cb);
161 }
162
bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB * client_cb)163 static void bta_hf_client_stop_at_resp_timer(tBTA_HF_CLIENT_CB* client_cb) {
164 alarm_cancel(client_cb->at_cb.resp_timer);
165 }
166
bta_hf_client_send_at(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_CMD cmd,const char * buf,uint16_t buf_len)167 static void bta_hf_client_send_at(tBTA_HF_CLIENT_CB* client_cb,
168 tBTA_HF_CLIENT_AT_CMD cmd, const char* buf,
169 uint16_t buf_len) {
170 APPL_TRACE_DEBUG("%s", __func__);
171 if ((client_cb->at_cb.current_cmd == BTA_HF_CLIENT_AT_NONE ||
172 !client_cb->svc_conn) &&
173 !alarm_is_scheduled(client_cb->at_cb.hold_timer)) {
174 uint16_t len;
175
176 #ifdef BTA_HF_CLIENT_AT_DUMP
177 APPL_TRACE_DEBUG("%s: %.*s", __func__, buf_len - 1, buf);
178 #endif
179
180 client_cb->at_cb.current_cmd = cmd;
181 /* Generate fake responses for these because they won't reliably work */
182 if (!service_availability &&
183 (cmd == BTA_HF_CLIENT_AT_CNUM || cmd == BTA_HF_CLIENT_AT_COPS)) {
184 APPL_TRACE_WARNING("%s: No service, skipping %d command", __func__, cmd);
185 bta_hf_client_handle_ok(client_cb);
186 return;
187 }
188
189 APPL_TRACE_DEBUG("%s: writing port data to %d", __func__,
190 client_cb->conn_handle);
191 PORT_WriteData(client_cb->conn_handle, buf, buf_len, &len);
192
193 bta_hf_client_start_at_resp_timer(client_cb);
194
195 return;
196 }
197
198 bta_hf_client_queue_at(client_cb, cmd, buf, buf_len);
199 }
200
bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB * client_cb)201 static void bta_hf_client_send_queued_at(tBTA_HF_CLIENT_CB* client_cb) {
202 tBTA_HF_CLIENT_AT_QCMD* cur = client_cb->at_cb.queued_cmd;
203
204 APPL_TRACE_DEBUG("%s", __func__);
205
206 if (cur != NULL) {
207 client_cb->at_cb.queued_cmd = cur->next;
208
209 bta_hf_client_send_at(client_cb, cur->cmd, cur->buf, cur->buf_len);
210
211 osi_free(cur);
212 }
213 }
214
bta_hf_client_at_hold_timer_cback(void * data)215 static void bta_hf_client_at_hold_timer_cback(void* data) {
216 tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
217 APPL_TRACE_DEBUG("%s", __func__);
218 bta_hf_client_send_queued_at(client_cb);
219 }
220
bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB * client_cb)221 static void bta_hf_client_stop_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
222 APPL_TRACE_DEBUG("%s", __func__);
223 alarm_cancel(client_cb->at_cb.hold_timer);
224 }
225
bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB * client_cb)226 static void bta_hf_client_start_at_hold_timer(tBTA_HF_CLIENT_CB* client_cb) {
227 APPL_TRACE_DEBUG("%s", __func__);
228 alarm_set_on_mloop(client_cb->at_cb.hold_timer, BTA_HF_CLIENT_AT_HOLD_TIMEOUT,
229 bta_hf_client_at_hold_timer_cback, (void*)client_cb);
230 }
231
232 /******************************************************************************
233 *
234 * COMMON AT EVENT HANDLING funcS
235 *
236 * Receives data (strings, ints, etc.) from the parser and processes this
237 * data. No buffer parsing is being done here.
238 ******************************************************************************/
239
bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB * client_cb)240 static void bta_hf_client_handle_ok(tBTA_HF_CLIENT_CB* client_cb) {
241 APPL_TRACE_DEBUG("%s", __func__);
242
243 bta_hf_client_stop_at_resp_timer(client_cb);
244
245 if (!client_cb->svc_conn) {
246 bta_hf_client_slc_seq(client_cb, false);
247 return;
248 }
249
250 switch (client_cb->at_cb.current_cmd) {
251 case BTA_HF_CLIENT_AT_BIA:
252 case BTA_HF_CLIENT_AT_BCC:
253 break;
254 case BTA_HF_CLIENT_AT_BCS:
255 bta_hf_client_start_at_hold_timer(client_cb);
256 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
257 return;
258 case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
259 if (!client_cb->send_at_reply) {
260 client_cb->send_at_reply = true;
261 }
262 break;
263 case BTA_HF_CLIENT_AT_NONE:
264 bta_hf_client_stop_at_hold_timer(client_cb);
265 break;
266 default:
267 if (client_cb->send_at_reply) {
268 bta_hf_client_at_result(client_cb, BTA_HF_CLIENT_AT_RESULT_OK, 0);
269 }
270 break;
271 }
272
273 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
274
275 bta_hf_client_send_queued_at(client_cb);
276 }
277
bta_hf_client_handle_error(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_RESULT_TYPE type,uint16_t cme)278 static void bta_hf_client_handle_error(tBTA_HF_CLIENT_CB* client_cb,
279 tBTA_HF_CLIENT_AT_RESULT_TYPE type,
280 uint16_t cme) {
281 APPL_TRACE_DEBUG("%s: %u %u", __func__, type, cme);
282
283 bta_hf_client_stop_at_resp_timer(client_cb);
284
285 if (!client_cb->svc_conn) {
286 bta_hf_client_slc_seq(client_cb, true);
287 return;
288 }
289
290 switch (client_cb->at_cb.current_cmd) {
291 case BTA_HF_CLIENT_AT_BIA:
292 break;
293 case BTA_HF_CLIENT_AT_BCC:
294 case BTA_HF_CLIENT_AT_BCS:
295 bta_hf_client_cback_sco(client_cb, BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
296 break;
297 case BTA_HF_CLIENT_AT_CLIP: // last cmd is post slc seq
298 if (!client_cb->send_at_reply) {
299 client_cb->send_at_reply = true;
300 }
301 break;
302 default:
303 if (client_cb->send_at_reply) {
304 bta_hf_client_at_result(client_cb, type, cme);
305 }
306 break;
307 }
308
309 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
310
311 bta_hf_client_send_queued_at(client_cb);
312 }
313
bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB * client_cb)314 static void bta_hf_client_handle_ring(tBTA_HF_CLIENT_CB* client_cb) {
315 APPL_TRACE_DEBUG("%s", __func__);
316 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_RING_INDICATION, 0);
317 }
318
bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)319 static void bta_hf_client_handle_brsf(tBTA_HF_CLIENT_CB* client_cb,
320 uint32_t value) {
321 APPL_TRACE_DEBUG("%s: 0x%x", __func__, value);
322 client_cb->peer_features = value;
323 }
324
325 /* handles a single indicator descriptor - registers it for value changing
326 * 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)327 static void bta_hf_client_handle_cind_list_item(tBTA_HF_CLIENT_CB* client_cb,
328 char* name, uint32_t min,
329 uint32_t max, uint32_t index) {
330 uint8_t i = 0;
331
332 APPL_TRACE_DEBUG("%s: %lu.%s <%lu:%lu>", __func__, index, name, min, max);
333
334 /* look for a matching indicator on list of supported ones */
335 for (i = 0; i < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT; i++) {
336 if (strcmp(name, BTA_HF_CLIENT_INDICATOR_SERVICE) == 0) {
337 service_index = index;
338 }
339 /* look for a match - search one sign further than indicators name to check
340 * for string end */
341 /* It will distinguish 'callheld' which could be matched by strncmp as
342 * 'call'. */
343 if (strncmp(name, bta_hf_client_indicators[i].name,
344 bta_hf_client_indicators[i].namelen) != 0)
345 continue;
346
347 /* index - enumerates value position in the incoming sequence */
348 /* if name matches one of the known indicators, add its incoming position */
349 /* to lookup table for easy value->indicator matching later, when only
350 * values come */
351 client_cb->at_cb.indicator_lookup[index] = i;
352
353 return;
354 }
355 }
356
bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB * client_cb,uint32_t index,uint32_t value)357 static void bta_hf_client_handle_cind_value(tBTA_HF_CLIENT_CB* client_cb,
358 uint32_t index, uint32_t value) {
359 APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
360
361 if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
362 return;
363 }
364
365 if (service_index == index) {
366 if (value == 0) {
367 service_availability = false;
368 } else {
369 service_availability = true;
370 }
371 }
372 if (client_cb->at_cb.indicator_lookup[index] == -1) {
373 return;
374 }
375
376 /* get the real array index from lookup table */
377 index = client_cb->at_cb.indicator_lookup[index];
378
379 /* Ignore out of range values */
380 if (value > bta_hf_client_indicators[index].max ||
381 value < bta_hf_client_indicators[index].min) {
382 return;
383 }
384
385 /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
386 bta_hf_client_ind(client_cb, index, value);
387 }
388
bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB * client_cb,uint32_t mask)389 static void bta_hf_client_handle_chld(tBTA_HF_CLIENT_CB* client_cb,
390 uint32_t mask) {
391 APPL_TRACE_DEBUG("%s: 0x%x", __func__, mask);
392
393 client_cb->chld_features |= mask;
394 }
395
bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB * client_cb,uint32_t index,uint32_t value)396 static void bta_hf_client_handle_ciev(tBTA_HF_CLIENT_CB* client_cb,
397 uint32_t index, uint32_t value) {
398 int8_t realind = -1;
399
400 APPL_TRACE_DEBUG("%s: index: %u value: %u", __func__, index, value);
401
402 if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
403 return;
404 }
405
406 if (service_index == index - 1) {
407 service_availability = value == 0 ? false : true;
408 }
409
410 realind = client_cb->at_cb.indicator_lookup[index - 1];
411
412 if (realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT) {
413 /* get the real in-array index from lookup table by index it comes at */
414 /* if there is no bug it should automatically be correctly calculated */
415 if (value > bta_hf_client_indicators[realind].max ||
416 value < bta_hf_client_indicators[realind].min) {
417 return;
418 }
419
420 /* update service availability on +ciev from AG. */
421 if (service_index == (index - 1)) {
422 if (value == 1) {
423 service_availability = true;
424 } else {
425 service_availability = false;
426 }
427 }
428
429 /* tBTA_HF_CLIENT_IND_TYPE match index in bta_hf_client_indicators */
430 bta_hf_client_ind(client_cb, realind, value);
431 }
432 }
433
bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)434 static void bta_hf_client_handle_bcs(tBTA_HF_CLIENT_CB* client_cb,
435 uint32_t codec) {
436 APPL_TRACE_DEBUG("%s: codec: %u sco listen state: %d", __func__, codec,
437 client_cb->sco_state);
438 if (codec == BTM_SCO_CODEC_CVSD || codec == BTM_SCO_CODEC_MSBC) {
439 client_cb->negotiated_codec = codec;
440 bta_hf_client_send_at_bcs(client_cb, codec);
441 } else {
442 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
443 bta_hf_client_send_at_bac(client_cb);
444 }
445 }
446
bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB * client_cb,uint32_t provided)447 static void bta_hf_client_handle_bsir(tBTA_HF_CLIENT_CB* client_cb,
448 uint32_t provided) {
449 APPL_TRACE_DEBUG("%s: %u", __func__, provided);
450
451 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BSIR_EVT, provided);
452 }
453
bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB * client_cb,uint32_t code)454 static void bta_hf_client_handle_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
455 uint32_t code) {
456 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_CME, code);
457 }
458
bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)459 static void bta_hf_client_handle_vgm(tBTA_HF_CLIENT_CB* client_cb,
460 uint32_t value) {
461 APPL_TRACE_DEBUG("%s: %lu", __func__, value);
462
463 if (value <= BTA_HF_CLIENT_VGM_MAX) {
464 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_MIC_EVT, value);
465 }
466 }
467
bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)468 static void bta_hf_client_handle_vgs(tBTA_HF_CLIENT_CB* client_cb,
469 uint32_t value) {
470 APPL_TRACE_DEBUG("%s: %lu", __func__, value);
471
472 if (value <= BTA_HF_CLIENT_VGS_MAX) {
473 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_SPK_EVT, value);
474 }
475 }
476
bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB * client_cb,uint32_t value)477 static void bta_hf_client_handle_bvra(tBTA_HF_CLIENT_CB* client_cb,
478 uint32_t value) {
479 APPL_TRACE_DEBUG("%s: %lu", __func__, value);
480
481 if (value > 1) {
482 return;
483 }
484
485 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_VOICE_REC_EVT, value);
486 }
487
bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint32_t type)488 static void bta_hf_client_handle_clip(tBTA_HF_CLIENT_CB* client_cb,
489 char* numstr, uint32_t type) {
490 APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
491
492 bta_hf_client_clip(client_cb, numstr);
493 }
494
bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint32_t type)495 static void bta_hf_client_handle_ccwa(tBTA_HF_CLIENT_CB* client_cb,
496 char* numstr, uint32_t type) {
497 APPL_TRACE_DEBUG("%s: %u %s", __func__, type, numstr);
498
499 bta_hf_client_ccwa(client_cb, numstr);
500 }
501
bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB * client_cb,char * opstr,uint32_t mode)502 static void bta_hf_client_handle_cops(tBTA_HF_CLIENT_CB* client_cb, char* opstr,
503 uint32_t mode) {
504 APPL_TRACE_DEBUG("%s: %u %s", __func__, mode, opstr);
505
506 bta_hf_client_operator_name(client_cb, opstr);
507 }
508
bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB * client_cb,char * numstr)509 static void bta_hf_client_handle_binp(tBTA_HF_CLIENT_CB* client_cb,
510 char* numstr) {
511 APPL_TRACE_DEBUG("%s: %s", __func__, numstr);
512
513 bta_hf_client_binp(client_cb, numstr);
514 }
515
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)516 static void bta_hf_client_handle_clcc(tBTA_HF_CLIENT_CB* client_cb,
517 uint16_t idx, uint16_t dir,
518 uint16_t status, uint16_t mode,
519 uint16_t mpty, char* numstr,
520 uint16_t type) {
521 APPL_TRACE_DEBUG("%s: idx: %u dir: %u status: %u mode: %u mpty: %u", __func__,
522 idx, dir, status, mode, mpty);
523
524 if (numstr) {
525 APPL_TRACE_DEBUG("%s: number: %s type: %u", __func__, numstr, type);
526 }
527
528 bta_hf_client_clcc(client_cb, idx, dir, status, mpty, numstr);
529 }
530
bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB * client_cb,char * numstr,uint16_t type,uint16_t service)531 static void bta_hf_client_handle_cnum(tBTA_HF_CLIENT_CB* client_cb,
532 char* numstr, uint16_t type,
533 uint16_t service) {
534 APPL_TRACE_DEBUG("%s: number: %s type: %u service: %u", __func__, numstr,
535 type, service);
536
537 /* TODO: should number be modified according to type? */
538 bta_hf_client_cnum(client_cb, numstr, service);
539 }
540
bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB * client_cb,uint16_t code)541 static void bta_hf_client_handle_btrh(tBTA_HF_CLIENT_CB* client_cb,
542 uint16_t code) {
543 APPL_TRACE_DEBUG("%s: %lu", __func__, code);
544
545 bta_hf_client_evt_val(client_cb, BTA_HF_CLIENT_BTRH_EVT, code);
546 }
547
548 /*******************************************************************************
549 *
550 * Function bta_hf_client_cback_ind
551 *
552 * Description Send indicator callback event to application.
553 *
554 * Returns void
555 *
556 ******************************************************************************/
bta_hf_client_ind(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_IND_TYPE type,uint16_t value)557 void bta_hf_client_ind(tBTA_HF_CLIENT_CB* client_cb,
558 tBTA_HF_CLIENT_IND_TYPE type, uint16_t value) {
559 tBTA_HF_CLIENT evt;
560
561 memset(&evt, 0, sizeof(evt));
562
563 evt.ind.type = type;
564 evt.ind.value = value;
565
566 evt.ind.bd_addr = client_cb->peer_addr;
567 bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
568 }
569
570 /*******************************************************************************
571 *
572 * Function bta_hf_client_evt_val
573 *
574 * Description Send event to application.
575 * This is a generic helper for events with common data.
576 *
577 *
578 * Returns void
579 *
580 ******************************************************************************/
bta_hf_client_evt_val(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_EVT type,uint16_t value)581 void bta_hf_client_evt_val(tBTA_HF_CLIENT_CB* client_cb,
582 tBTA_HF_CLIENT_EVT type, uint16_t value) {
583 tBTA_HF_CLIENT evt;
584
585 memset(&evt, 0, sizeof(evt));
586
587 evt.val.bd_addr = client_cb->peer_addr;
588 evt.val.value = value;
589
590 bta_hf_client_app_callback(type, &evt);
591 }
592
593 /*******************************************************************************
594 *
595 * Function bta_hf_client_operator_name
596 *
597 * Description Send operator name event to application.
598 *
599 *
600 * Returns void
601 *
602 ******************************************************************************/
bta_hf_client_operator_name(tBTA_HF_CLIENT_CB * client_cb,char * name)603 void bta_hf_client_operator_name(tBTA_HF_CLIENT_CB* client_cb, char* name) {
604 tBTA_HF_CLIENT evt;
605
606 memset(&evt, 0, sizeof(evt));
607
608 strlcpy(evt.operator_name.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
609 evt.operator_name.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
610
611 evt.operator_name.bd_addr = client_cb->peer_addr;
612 bta_hf_client_app_callback(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
613 }
614
615 /*******************************************************************************
616 *
617 * Function bta_hf_client_clip
618 *
619 * Description Send CLIP event to application.
620 *
621 *
622 * Returns void
623 *
624 ******************************************************************************/
bta_hf_client_clip(tBTA_HF_CLIENT_CB * client_cb,char * number)625 void bta_hf_client_clip(tBTA_HF_CLIENT_CB* client_cb, char* number) {
626 tBTA_HF_CLIENT evt;
627
628 memset(&evt, 0, sizeof(evt));
629
630 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
631 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
632
633 evt.number.bd_addr = client_cb->peer_addr;
634 bta_hf_client_app_callback(BTA_HF_CLIENT_CLIP_EVT, &evt);
635 }
636
637 /*******************************************************************************
638 *
639 * Function bta_hf_client_ccwa
640 *
641 * Description Send CLIP event to application.
642 *
643 *
644 * Returns void
645 *
646 ******************************************************************************/
bta_hf_client_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * number)647 void bta_hf_client_ccwa(tBTA_HF_CLIENT_CB* client_cb, char* number) {
648 tBTA_HF_CLIENT evt;
649
650 memset(&evt, 0, sizeof(evt));
651
652 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
653 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
654
655 evt.number.bd_addr = client_cb->peer_addr;
656 bta_hf_client_app_callback(BTA_HF_CLIENT_CCWA_EVT, &evt);
657 }
658
659 /*******************************************************************************
660 *
661 * Function bta_hf_client_at_result
662 *
663 * Description Send AT result event to application.
664 *
665 *
666 * Returns void
667 *
668 ******************************************************************************/
bta_hf_client_at_result(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_AT_RESULT_TYPE type,uint16_t cme)669 void bta_hf_client_at_result(tBTA_HF_CLIENT_CB* client_cb,
670 tBTA_HF_CLIENT_AT_RESULT_TYPE type, uint16_t cme) {
671 tBTA_HF_CLIENT evt;
672
673 memset(&evt, 0, sizeof(evt));
674
675 evt.result.type = type;
676 evt.result.cme = cme;
677
678 evt.result.bd_addr = client_cb->peer_addr;
679 bta_hf_client_app_callback(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
680 }
681
682 /*******************************************************************************
683 *
684 * Function bta_hf_client_clcc
685 *
686 * Description Send clcc event to application.
687 *
688 *
689 * Returns void
690 *
691 ******************************************************************************/
bta_hf_client_clcc(tBTA_HF_CLIENT_CB * client_cb,uint32_t idx,bool incoming,uint8_t status,bool mpty,char * number)692 void bta_hf_client_clcc(tBTA_HF_CLIENT_CB* client_cb, uint32_t idx,
693 bool incoming, uint8_t status, bool mpty,
694 char* number) {
695 tBTA_HF_CLIENT evt;
696
697 memset(&evt, 0, sizeof(evt));
698
699 evt.clcc.idx = idx;
700 evt.clcc.inc = incoming;
701 evt.clcc.status = status;
702 evt.clcc.mpty = mpty;
703
704 if (number) {
705 evt.clcc.number_present = true;
706 strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
707 evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
708 }
709
710 evt.clcc.bd_addr = client_cb->peer_addr;
711 bta_hf_client_app_callback(BTA_HF_CLIENT_CLCC_EVT, &evt);
712 }
713
714 /*******************************************************************************
715 *
716 * Function bta_hf_client_cnum
717 *
718 * Description Send cnum event to application.
719 *
720 *
721 * Returns void
722 *
723 ******************************************************************************/
bta_hf_client_cnum(tBTA_HF_CLIENT_CB * client_cb,char * number,uint16_t service)724 void bta_hf_client_cnum(tBTA_HF_CLIENT_CB* client_cb, char* number,
725 uint16_t service) {
726 tBTA_HF_CLIENT evt = {};
727
728 evt.cnum.service = service;
729 strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
730 evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
731
732 evt.cnum.bd_addr = client_cb->peer_addr;
733 bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
734 }
735
bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB * client_cb,const char * evt_buffer)736 void bta_hf_client_unknown_response(tBTA_HF_CLIENT_CB* client_cb,
737 const char* evt_buffer) {
738 tBTA_HF_CLIENT evt = {};
739
740 strlcpy(evt.unknown.event_string, evt_buffer,
741 BTA_HF_CLIENT_UNKOWN_EVENT_LEN + 1);
742 evt.unknown.event_string[BTA_HF_CLIENT_UNKOWN_EVENT_LEN] = '\0';
743
744 evt.unknown.bd_addr = client_cb->peer_addr;
745 bta_hf_client_app_callback(BTA_HF_CLIENT_UNKNOWN_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 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
bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1448 static char* bta_hf_client_process_unknown(tBTA_HF_CLIENT_CB* client_cb,
1449 char* buffer) {
1450 char* start = strstr(buffer, "\r\n");
1451 if (start == NULL) {
1452 return NULL;
1453 }
1454 start += sizeof("\r\n") - 1;
1455
1456 char* end = strstr(start, "\r\n");
1457 if (end == NULL) {
1458 return NULL;
1459 }
1460
1461 int evt_size = end - start + 1;
1462
1463 char tmp_buf[BTA_HF_CLIENT_UNKOWN_EVENT_LEN];
1464 if (evt_size < BTA_HF_CLIENT_UNKOWN_EVENT_LEN) {
1465 strlcpy(tmp_buf, start, evt_size);
1466 bta_hf_client_unknown_response(client_cb, tmp_buf);
1467 AT_CHECK_RN(end);
1468 } else {
1469 APPL_TRACE_ERROR("%s: exceed event buffer size. (%d, %d)", __func__,
1470 evt_size, BTA_HF_CLIENT_UNKOWN_EVENT_LEN);
1471 }
1472
1473 APPL_TRACE_DEBUG("%s: %s", __func__, buffer);
1474
1475 return end;
1476 }
1477
1478 /******************************************************************************
1479 * SUPPORTED EVENT MESSAGES
1480 ******************************************************************************/
1481
1482 /* returned values are as follow:
1483 * != NULL && != buf : match and parsed ok
1484 * == NULL : match but parse failed
1485 * != NULL && == buf : no match
1486 */
1487 typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
1488
1489 static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
1490 bta_hf_client_parse_ok, bta_hf_client_parse_error,
1491 bta_hf_client_parse_ring, bta_hf_client_parse_brsf,
1492 bta_hf_client_parse_cind, bta_hf_client_parse_ciev,
1493 bta_hf_client_parse_chld, bta_hf_client_parse_bcs,
1494 bta_hf_client_parse_bsir, bta_hf_client_parse_cmeerror,
1495 bta_hf_client_parse_vgm, bta_hf_client_parse_vgme,
1496 bta_hf_client_parse_vgs, bta_hf_client_parse_vgse,
1497 bta_hf_client_parse_bvra, bta_hf_client_parse_clip,
1498 bta_hf_client_parse_ccwa, bta_hf_client_parse_cops,
1499 bta_hf_client_parse_binp, bta_hf_client_parse_clcc,
1500 bta_hf_client_parse_cnum, bta_hf_client_parse_btrh,
1501 bta_hf_client_parse_busy, bta_hf_client_parse_delayed,
1502 bta_hf_client_parse_no_carrier, bta_hf_client_parse_no_answer,
1503 bta_hf_client_parse_blacklisted, bta_hf_client_process_unknown};
1504
1505 /* calculate supported event list length */
1506 static const uint16_t bta_hf_client_parser_cb_count =
1507 sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
1508
1509 #ifdef BTA_HF_CLIENT_AT_DUMP
bta_hf_client_dump_at(tBTA_HF_CLIENT_CB * client_cb)1510 static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
1511 char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
1512 char *p1, *p2;
1513
1514 p1 = client_cb->at_cb.buf;
1515 p2 = dump;
1516
1517 while (*p1 != '\0') {
1518 if (*p1 == '\r') {
1519 strlcpy(p2, "<cr>", 4);
1520 p2 += 4;
1521 } else if (*p1 == '\n') {
1522 strlcpy(p2, "<lf>", 4);
1523 p2 += 4;
1524 } else {
1525 *p2 = *p1;
1526 p2++;
1527 }
1528 p1++;
1529 }
1530
1531 *p2 = '\0';
1532
1533 APPL_TRACE_DEBUG("%s: %s", __func__, dump);
1534 }
1535 #endif
1536
bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB * client_cb)1537 static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
1538 char* buf = client_cb->at_cb.buf;
1539
1540 APPL_TRACE_DEBUG("%s", __func__);
1541
1542 #ifdef BTA_HF_CLIENT_AT_DUMP
1543 bta_hf_client_dump_at(client_cb);
1544 #endif
1545
1546 while (*buf != '\0') {
1547 int i;
1548 char* tmp = NULL;
1549
1550 for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
1551 tmp = bta_hf_client_parser_cb[i](client_cb, buf);
1552 if (tmp == NULL) {
1553 APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
1554 tmp = bta_hf_client_skip_unknown(client_cb, buf);
1555 break;
1556 }
1557
1558 /* matched or unknown skipped, if unknown failed tmp is NULL so
1559 this is also handled */
1560 if (tmp != buf) {
1561 buf = tmp;
1562 break;
1563 }
1564 }
1565
1566 /* could not skip unknown (received garbage?)... disconnect */
1567 if (tmp == NULL) {
1568 APPL_TRACE_ERROR(
1569 "HFPCient: could not skip unknown AT event, disconnecting");
1570 bta_hf_client_at_reset(client_cb);
1571
1572 tBTA_HF_CLIENT_DATA msg;
1573 msg.hdr.layer_specific = client_cb->handle;
1574 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1575 return;
1576 }
1577
1578 buf = tmp;
1579 }
1580 }
1581
bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB * client_cb)1582 static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
1583 bool ret = false;
1584 tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
1585
1586 if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
1587 if (at_cb->buf[at_cb->offset - 2] == '\r' &&
1588 at_cb->buf[at_cb->offset - 1] == '\n') {
1589 ret = true;
1590 }
1591 }
1592
1593 APPL_TRACE_DEBUG("%s: %d", __func__, ret);
1594
1595 return ret;
1596 }
1597
bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB * client_cb)1598 static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
1599 memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
1600 client_cb->at_cb.offset = 0;
1601 }
1602
1603 /******************************************************************************
1604 *
1605 * MAIN PARSING FUNCTION
1606 *
1607 *
1608 ******************************************************************************/
bta_hf_client_at_parse(tBTA_HF_CLIENT_CB * client_cb,char * buf,unsigned int len)1609 void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
1610 unsigned int len) {
1611 APPL_TRACE_DEBUG("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset,
1612 len);
1613
1614 if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
1615 char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
1616 unsigned int tmp = client_cb->at_cb.offset;
1617 unsigned int space_left =
1618 BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
1619
1620 APPL_TRACE_DEBUG("%s: overrun, trying to recover", __func__);
1621
1622 /* fill up parser buffer */
1623 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
1624 len -= space_left;
1625 buf += space_left;
1626 client_cb->at_cb.offset += space_left;
1627
1628 /* find end of last complete command before proceeding */
1629 while (!bta_hf_client_check_at_complete(client_cb)) {
1630 if (client_cb->at_cb.offset == 0) {
1631 APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");
1632
1633 bta_hf_client_at_reset(client_cb);
1634
1635 tBTA_HF_CLIENT_DATA msg;
1636 msg.hdr.layer_specific = client_cb->handle;
1637 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1638 return;
1639 }
1640
1641 client_cb->at_cb.offset--;
1642 }
1643
1644 /* cut buffer to complete AT event and keep cut data */
1645 tmp += space_left - client_cb->at_cb.offset;
1646 memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
1647 client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
1648
1649 /* parse */
1650 bta_hf_client_at_parse_start(client_cb);
1651 bta_hf_client_at_clear_buf(client_cb);
1652
1653 /* recover cut data */
1654 memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
1655 client_cb->at_cb.offset += tmp;
1656 }
1657
1658 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
1659 client_cb->at_cb.offset += len;
1660
1661 /* If last event is complete, parsing can be started */
1662 if (bta_hf_client_check_at_complete(client_cb)) {
1663 bta_hf_client_at_parse_start(client_cb);
1664 bta_hf_client_at_clear_buf(client_cb);
1665 }
1666 }
1667
bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_FEAT features)1668 void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
1669 tBTA_HF_CLIENT_FEAT features) {
1670 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1671 int at_len;
1672
1673 APPL_TRACE_DEBUG("%s", __func__);
1674
1675 at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
1676 if (at_len < 0) {
1677 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1678 return;
1679 }
1680
1681 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
1682 }
1683
bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB * client_cb)1684 void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
1685 const char* buf;
1686
1687 APPL_TRACE_DEBUG("%s", __func__);
1688
1689 buf = "AT+BAC=1,2\r";
1690
1691 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
1692 }
1693
bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)1694 void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
1695 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1696 int at_len;
1697
1698 APPL_TRACE_DEBUG("%s", __func__);
1699
1700 at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
1701 if (at_len < 0) {
1702 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1703 return;
1704 }
1705
1706 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
1707 }
1708
bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB * client_cb,bool status)1709 void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
1710 const char* buf;
1711 tBTA_HF_CLIENT_AT_CMD cmd;
1712
1713 APPL_TRACE_DEBUG("%s", __func__);
1714
1715 if (status) {
1716 buf = "AT+CIND?\r";
1717 cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
1718 } else {
1719 buf = "AT+CIND=?\r";
1720 cmd = BTA_HF_CLIENT_AT_CIND;
1721 }
1722
1723 bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
1724 }
1725
bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB * client_cb,bool activate)1726 void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1727 const char* buf;
1728
1729 APPL_TRACE_DEBUG("%s", __func__);
1730
1731 if (activate)
1732 buf = "AT+CMER=3,0,0,1\r";
1733 else
1734 buf = "AT+CMER=3,0,0,0\r";
1735
1736 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
1737 }
1738
bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB * client_cb,char cmd,uint32_t idx)1739 void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
1740 uint32_t idx) {
1741 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1742 int at_len;
1743
1744 APPL_TRACE_DEBUG("%s", __func__);
1745
1746 if (idx > 0)
1747 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
1748 else
1749 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
1750
1751 if (at_len < 0) {
1752 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1753 return;
1754 }
1755
1756 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
1757 }
1758
bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB * client_cb,bool activate)1759 void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1760 const char* buf;
1761
1762 APPL_TRACE_DEBUG("%s", __func__);
1763
1764 if (activate)
1765 buf = "AT+CLIP=1\r";
1766 else
1767 buf = "AT+CLIP=0\r";
1768
1769 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
1770 }
1771
bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB * client_cb,bool activate)1772 void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1773 const char* buf;
1774
1775 APPL_TRACE_DEBUG("%s", __func__);
1776
1777 if (activate)
1778 buf = "AT+CCWA=1\r";
1779 else
1780 buf = "AT+CCWA=0\r";
1781
1782 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
1783 }
1784
bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB * client_cb,bool activate)1785 void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1786 const char* buf;
1787
1788 APPL_TRACE_DEBUG("%s", __func__);
1789
1790 if (activate)
1791 buf = "AT+CMEE=1\r";
1792 else
1793 buf = "AT+CMEE=0\r";
1794
1795 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
1796 }
1797
bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB * client_cb,bool query)1798 void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
1799 const char* buf;
1800
1801 APPL_TRACE_DEBUG("%s", __func__);
1802
1803 if (query)
1804 buf = "AT+COPS?\r";
1805 else
1806 buf = "AT+COPS=3,0\r";
1807
1808 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
1809 }
1810
bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB * client_cb)1811 void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
1812 const char* buf;
1813
1814 APPL_TRACE_DEBUG("%s", __func__);
1815
1816 buf = "AT+CLCC\r";
1817
1818 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
1819 }
1820
bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB * client_cb,bool enable)1821 void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
1822 const char* buf;
1823
1824 APPL_TRACE_DEBUG("%s", __func__);
1825
1826 if (enable)
1827 buf = "AT+BVRA=1\r";
1828 else
1829 buf = "AT+BVRA=0\r";
1830
1831 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
1832 }
1833
bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1834 void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1835 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1836 int at_len;
1837
1838 APPL_TRACE_DEBUG("%s", __func__);
1839
1840 at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
1841 if (at_len < 0) {
1842 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1843 return;
1844 }
1845
1846 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
1847 }
1848
bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1849 void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1850 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1851 int at_len;
1852
1853 APPL_TRACE_DEBUG("%s", __func__);
1854
1855 at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
1856 if (at_len < 0) {
1857 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1858 return;
1859 }
1860
1861 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
1862 }
1863
bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB * client_cb,char * number,uint32_t memory)1864 void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number,
1865 uint32_t memory) {
1866 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1867 int at_len;
1868
1869 APPL_TRACE_DEBUG("%s", __func__);
1870
1871 if (number[0] != '\0') {
1872 at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
1873 } else {
1874 at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
1875 }
1876
1877 if (at_len < 0) {
1878 APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
1879 return;
1880 }
1881
1882 at_len = MIN((size_t)at_len, sizeof(buf));
1883
1884 if (at_len < 0) {
1885 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1886 return;
1887 }
1888 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
1889 }
1890
bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB * client_cb)1891 void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
1892 const char* buf;
1893
1894 APPL_TRACE_DEBUG("%s", __func__);
1895
1896 buf = "AT+BLDN\r";
1897
1898 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
1899 }
1900
bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB * client_cb)1901 void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
1902 const char* buf;
1903
1904 APPL_TRACE_DEBUG("%s", __func__);
1905
1906 buf = "ATA\r";
1907
1908 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
1909 }
1910
bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB * client_cb)1911 void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
1912 const char* buf;
1913
1914 APPL_TRACE_DEBUG("%s", __func__);
1915
1916 buf = "AT+CHUP\r";
1917
1918 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
1919 }
1920
bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB * client_cb,bool query,uint32_t val)1921 void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
1922 uint32_t val) {
1923 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1924 int at_len;
1925
1926 APPL_TRACE_DEBUG("%s", __func__);
1927
1928 if (query) {
1929 at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
1930 } else {
1931 at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
1932 }
1933
1934 if (at_len < 0) {
1935 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1936 return;
1937 }
1938
1939 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
1940 }
1941
bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB * client_cb,char code)1942 void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
1943 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1944 int at_len;
1945
1946 APPL_TRACE_DEBUG("%s", __func__);
1947
1948 at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
1949
1950 if (at_len < 0) {
1951 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1952 return;
1953 }
1954
1955 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
1956 }
1957
bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB * client_cb)1958 void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
1959 const char* buf;
1960
1961 APPL_TRACE_DEBUG("%s", __func__);
1962
1963 buf = "AT+BCC\r";
1964
1965 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
1966 }
1967
bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB * client_cb)1968 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
1969 const char* buf;
1970
1971 APPL_TRACE_DEBUG("%s", __func__);
1972
1973 buf = "AT+CNUM\r";
1974
1975 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
1976 }
1977
bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB * client_cb)1978 void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
1979 const char* buf;
1980
1981 APPL_TRACE_DEBUG("%s", __func__);
1982
1983 if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
1984 APPL_TRACE_ERROR("%s: Remote does not support NREC.", __func__);
1985 return;
1986 }
1987
1988 buf = "AT+NREC=0\r";
1989
1990 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
1991 }
1992
bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB * client_cb,uint32_t action)1993 void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
1994 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1995 int at_len;
1996
1997 APPL_TRACE_DEBUG("%s", __func__);
1998
1999 at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
2000
2001 if (at_len < 0) {
2002 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
2003 return;
2004 }
2005
2006 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
2007 }
2008
bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB * client_cb)2009 void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
2010 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2011 int at_len;
2012 int i;
2013
2014 APPL_TRACE_DEBUG("%s", __func__);
2015 if (client_cb->peer_version < HFP_VERSION_1_6) {
2016 APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
2017 return;
2018 }
2019
2020 at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
2021
2022 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2023 int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
2024
2025 at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
2026 }
2027
2028 buf[at_len - 1] = '\r';
2029
2030 if (at_len < 0) {
2031 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
2032 return;
2033 }
2034
2035 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
2036 }
2037
bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB * client_cb,const char * str)2038 void bta_hf_client_send_at_vendor_specific_cmd(tBTA_HF_CLIENT_CB* client_cb,
2039 const char* str) {
2040 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2041
2042 APPL_TRACE_DEBUG("%s", __func__);
2043
2044 int at_len = snprintf(buf, sizeof(buf), "AT%s", str);
2045
2046 if (at_len < 1) {
2047 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
2048 return;
2049 }
2050
2051 buf[at_len - 1] = '\r';
2052
2053 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VENDOR_SPECIFIC, buf,
2054 at_len);
2055 }
2056
bta_hf_client_at_init(tBTA_HF_CLIENT_CB * client_cb)2057 void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
2058 alarm_free(client_cb->at_cb.resp_timer);
2059 alarm_free(client_cb->at_cb.hold_timer);
2060 memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
2061 client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
2062 client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
2063 bta_hf_client_at_reset(client_cb);
2064 }
2065
bta_hf_client_at_reset(tBTA_HF_CLIENT_CB * client_cb)2066 void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
2067 int i;
2068
2069 bta_hf_client_stop_at_resp_timer(client_cb);
2070 bta_hf_client_stop_at_hold_timer(client_cb);
2071
2072 bta_hf_client_clear_queued_at(client_cb);
2073
2074 bta_hf_client_at_clear_buf(client_cb);
2075
2076 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2077 client_cb->at_cb.indicator_lookup[i] = -1;
2078 }
2079
2080 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
2081 }
2082
bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA * p_data)2083 void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
2084 tBTA_HF_CLIENT_CB* client_cb =
2085 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
2086 if (!client_cb) {
2087 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
2088 p_data->hdr.layer_specific);
2089 return;
2090 }
2091
2092 tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
2093 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2094
2095 APPL_TRACE_DEBUG("%s: at cmd: %d", __func__, p_val->uint8_val);
2096 switch (p_val->uint8_val) {
2097 case BTA_HF_CLIENT_AT_CMD_VTS:
2098 bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
2099 break;
2100 case BTA_HF_CLIENT_AT_CMD_BTRH:
2101 bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
2102 break;
2103 case BTA_HF_CLIENT_AT_CMD_CHUP:
2104 bta_hf_client_send_at_chup(client_cb);
2105 break;
2106 case BTA_HF_CLIENT_AT_CMD_CHLD:
2107 /* expects ascii code for command */
2108 bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
2109 p_val->uint32_val2);
2110 break;
2111 case BTA_HF_CLIENT_AT_CMD_BCC:
2112 bta_hf_client_send_at_bcc(client_cb);
2113 break;
2114 case BTA_HF_CLIENT_AT_CMD_CNUM:
2115 bta_hf_client_send_at_cnum(client_cb);
2116 break;
2117 case BTA_HF_CLIENT_AT_CMD_ATA:
2118 bta_hf_client_send_at_ata(client_cb);
2119 break;
2120 case BTA_HF_CLIENT_AT_CMD_COPS:
2121 bta_hf_client_send_at_cops(client_cb, true);
2122 break;
2123 case BTA_HF_CLIENT_AT_CMD_ATD:
2124 bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
2125 break;
2126 case BTA_HF_CLIENT_AT_CMD_VGM:
2127 bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
2128 break;
2129 case BTA_HF_CLIENT_AT_CMD_VGS:
2130 bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
2131 break;
2132 case BTA_HF_CLIENT_AT_CMD_BVRA:
2133 bta_hf_client_send_at_bvra(client_cb,
2134 p_val->uint32_val1 == 0 ? false : true);
2135 break;
2136 case BTA_HF_CLIENT_AT_CMD_CLCC:
2137 bta_hf_client_send_at_clcc(client_cb);
2138 break;
2139 case BTA_HF_CLIENT_AT_CMD_BINP:
2140 bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
2141 break;
2142 case BTA_HF_CLIENT_AT_CMD_BLDN:
2143 bta_hf_client_send_at_bldn(client_cb);
2144 break;
2145 case BTA_HF_CLIENT_AT_CMD_NREC:
2146 bta_hf_client_send_at_nrec(client_cb);
2147 break;
2148 case BTA_HF_CLIENT_AT_CMD_VENDOR_SPECIFIC_CMD:
2149 bta_hf_client_send_at_vendor_specific_cmd(client_cb, p_val->str);
2150 break;
2151 default:
2152 APPL_TRACE_ERROR("Default case");
2153 snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
2154 "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val,
2155 p_val->uint32_val1, p_val->uint32_val2, p_val->str);
2156 APPL_TRACE_ERROR("%s: AT buffer: %s ", __func__, buf);
2157 break;
2158 }
2159 }
2160