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 memset(&evt, 0, sizeof(evt));
730
731 evt.cnum.service = service;
732 strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
733 evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
734
735 evt.cnum.bd_addr = client_cb->peer_addr;
736 bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
737 }
738
739 /*******************************************************************************
740 *
741 * Function bta_hf_client_binp
742 *
743 * Description Send BINP event to application.
744 *
745 *
746 * Returns void
747 *
748 ******************************************************************************/
bta_hf_client_binp(tBTA_HF_CLIENT_CB * client_cb,char * number)749 void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
750 tBTA_HF_CLIENT evt;
751
752 memset(&evt, 0, sizeof(evt));
753
754 strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
755 evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
756
757 evt.number.bd_addr = client_cb->peer_addr;
758 bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
759 }
760
761 /******************************************************************************
762 *
763 * COMMON AT EVENTS PARSING FUNCTIONS
764 *
765 ******************************************************************************/
766
767 /* Check if prefix match and skip spaces if any */
768 #define AT_CHECK_EVENT(buf, event) \
769 do { \
770 if (strncmp("\r\n" event, buf, sizeof("\r\n" event) - 1) != 0) return buf; \
771 (buf) += sizeof("\r\n" event) - 1; \
772 while (*(buf) == ' ') (buf)++; \
773 } while (0)
774
775 /* check for <cr><lf> and forward buffer if match */
776 #define AT_CHECK_RN(buf) \
777 do { \
778 if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \
779 APPL_TRACE_DEBUG("%s: missing end <cr><lf>", __func__); \
780 return NULL; \
781 } \
782 (buf) += sizeof("\r\n") - 1; \
783 } while (0)
784
785 /* skip rest of AT string up to <cr> */
786 #define AT_SKIP_REST(buf) \
787 do { \
788 while (*(buf) != '\r') (buf)++; \
789 } while (0)
790
bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB * client_cb,char * buffer)791 static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb,
792 char* buffer) {
793 AT_CHECK_EVENT(buffer, "OK");
794 AT_CHECK_RN(buffer);
795
796 bta_hf_client_handle_ok(client_cb);
797
798 return buffer;
799 }
800
bta_hf_client_parse_error(tBTA_HF_CLIENT_CB * client_cb,char * buffer)801 static char* bta_hf_client_parse_error(tBTA_HF_CLIENT_CB* client_cb,
802 char* buffer) {
803 AT_CHECK_EVENT(buffer, "ERROR");
804 AT_CHECK_RN(buffer);
805
806 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
807
808 return buffer;
809 }
810
bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB * client_cb,char * buffer)811 static char* bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB* client_cb,
812 char* buffer) {
813 AT_CHECK_EVENT(buffer, "RING");
814 AT_CHECK_RN(buffer);
815
816 bta_hf_client_handle_ring(client_cb);
817
818 return buffer;
819 }
820
821 /* 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))822 static char* bta_hf_client_parse_uint32(
823 tBTA_HF_CLIENT_CB* client_cb, char* buffer,
824 void (*handler_callback)(tBTA_HF_CLIENT_CB*, uint32_t)) {
825 uint32_t value;
826 int res;
827 int offset;
828
829 res = sscanf(buffer, "%u%n", &value, &offset);
830 if (res < 1) {
831 return NULL;
832 }
833
834 buffer += offset;
835
836 AT_CHECK_RN(buffer);
837
838 handler_callback(client_cb, value);
839 return buffer;
840 }
841
bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB * client_cb,char * buffer)842 static char* bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB* client_cb,
843 char* buffer) {
844 AT_CHECK_EVENT(buffer, "+BRSF:");
845
846 return bta_hf_client_parse_uint32(client_cb, buffer,
847 bta_hf_client_handle_brsf);
848 }
849
bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB * client_cb,char * buffer)850 static char* bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB* client_cb,
851 char* buffer) {
852 /* value and its position */
853 uint16_t index = 0;
854 uint32_t value = 0;
855
856 int offset;
857 int res;
858
859 while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
860 /* decides if its valid index and value, if yes stores it */
861 bta_hf_client_handle_cind_value(client_cb, index, value);
862
863 buffer += offset;
864
865 /* check if more values are present */
866 if (*buffer != ',') {
867 break;
868 }
869
870 index++;
871 buffer++;
872 }
873
874 if (res > 0) {
875 AT_CHECK_RN(buffer);
876 return buffer;
877 }
878
879 return NULL;
880 }
881
bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB * client_cb,char * buffer)882 static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb,
883 char* buffer) {
884 int offset = 0;
885 char name[129];
886 uint32_t min, max;
887 uint32_t index = 0;
888 int res;
889
890 while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min,
891 &max, &offset)) > 2) {
892 bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index);
893 if (offset == 0) {
894 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
895 return NULL;
896 }
897
898 buffer += offset;
899 index++;
900
901 if (*buffer != ',') {
902 break;
903 }
904
905 buffer++;
906 }
907
908 if (res > 2) {
909 AT_CHECK_RN(buffer);
910 return buffer;
911 }
912
913 return NULL;
914 }
915
bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB * client_cb,char * buffer)916 static char* bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB* client_cb,
917 char* buffer) {
918 AT_CHECK_EVENT(buffer, "+CIND:");
919
920 if (*buffer == '(') return bta_hf_client_parse_cind_list(client_cb, buffer);
921
922 return bta_hf_client_parse_cind_values(client_cb, buffer);
923 }
924
bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB * client_cb,char * buffer)925 static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb,
926 char* buffer) {
927 AT_CHECK_EVENT(buffer, "+CHLD:");
928
929 if (*buffer != '(') {
930 return NULL;
931 }
932
933 buffer++;
934
935 while (*buffer != '\0') {
936 if (strncmp("0", buffer, 1) == 0) {
937 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL);
938 buffer++;
939 } else if (strncmp("1x", buffer, 2) == 0) {
940 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_X);
941 buffer += 2;
942 } else if (strncmp("1", buffer, 1) == 0) {
943 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_ACC);
944 buffer++;
945 } else if (strncmp("2x", buffer, 2) == 0) {
946 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_PRIV_X);
947 buffer += 2;
948 } else if (strncmp("2", buffer, 1) == 0) {
949 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_HOLD_ACC);
950 buffer++;
951 } else if (strncmp("3", buffer, 1) == 0) {
952 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE);
953 buffer++;
954 } else if (strncmp("4", buffer, 1) == 0) {
955 bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE_DETACH);
956 buffer++;
957 } else {
958 return NULL;
959 }
960
961 if (*buffer == ',') {
962 buffer++;
963 continue;
964 }
965
966 if (*buffer == ')') {
967 buffer++;
968 break;
969 }
970
971 return NULL;
972 }
973
974 AT_CHECK_RN(buffer);
975
976 return buffer;
977 }
978
bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB * client_cb,char * buffer)979 static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb,
980 char* buffer) {
981 uint32_t index, value;
982 int res;
983 int offset = 0;
984
985 AT_CHECK_EVENT(buffer, "+CIEV:");
986
987 res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
988 if (res < 2) {
989 return NULL;
990 }
991
992 if (offset == 0) {
993 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
994 return NULL;
995 }
996
997 buffer += offset;
998
999 AT_CHECK_RN(buffer);
1000
1001 bta_hf_client_handle_ciev(client_cb, index, value);
1002 return buffer;
1003 }
1004
bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1005 static char* bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB* client_cb,
1006 char* buffer) {
1007 AT_CHECK_EVENT(buffer, "+BCS:");
1008
1009 return bta_hf_client_parse_uint32(client_cb, buffer,
1010 bta_hf_client_handle_bcs);
1011 }
1012
bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1013 static char* bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB* client_cb,
1014 char* buffer) {
1015 AT_CHECK_EVENT(buffer, "+BSIR:");
1016
1017 return bta_hf_client_parse_uint32(client_cb, buffer,
1018 bta_hf_client_handle_bsir);
1019 }
1020
bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1021 static char* bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
1022 char* buffer) {
1023 AT_CHECK_EVENT(buffer, "+CME ERROR:");
1024
1025 return bta_hf_client_parse_uint32(client_cb, buffer,
1026 bta_hf_client_handle_cmeerror);
1027 }
1028
bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1029 static char* bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB* client_cb,
1030 char* buffer) {
1031 AT_CHECK_EVENT(buffer, "+VGM:");
1032
1033 return bta_hf_client_parse_uint32(client_cb, buffer,
1034 bta_hf_client_handle_vgm);
1035 }
1036
bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1037 static char* bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB* client_cb,
1038 char* buffer) {
1039 AT_CHECK_EVENT(buffer, "+VGM=");
1040
1041 return bta_hf_client_parse_uint32(client_cb, buffer,
1042 bta_hf_client_handle_vgm);
1043 }
1044
bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1045 static char* bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB* client_cb,
1046 char* buffer) {
1047 AT_CHECK_EVENT(buffer, "+VGS:");
1048
1049 return bta_hf_client_parse_uint32(client_cb, buffer,
1050 bta_hf_client_handle_vgs);
1051 }
1052
bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1053 static char* bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB* client_cb,
1054 char* buffer) {
1055 AT_CHECK_EVENT(buffer, "+VGS=");
1056
1057 return bta_hf_client_parse_uint32(client_cb, buffer,
1058 bta_hf_client_handle_vgs);
1059 }
1060
bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1061 static char* bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB* client_cb,
1062 char* buffer) {
1063 AT_CHECK_EVENT(buffer, "+BVRA:");
1064
1065 return bta_hf_client_parse_uint32(client_cb, buffer,
1066 bta_hf_client_handle_bvra);
1067 }
1068
bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1069 static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb,
1070 char* buffer) {
1071 /* spec forces 32 chars, plus \0 here */
1072 char number[33];
1073 uint32_t type = 0;
1074 int res;
1075 int offset = 0;
1076
1077 AT_CHECK_EVENT(buffer, "+CLIP:");
1078
1079 /* there might be something more after %lu but HFP doesn't care */
1080 res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1081 if (res < 2) {
1082 return NULL;
1083 }
1084
1085 if (offset == 0) {
1086 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1087 return NULL;
1088 }
1089
1090 buffer += offset;
1091
1092 AT_SKIP_REST(buffer);
1093
1094 AT_CHECK_RN(buffer);
1095
1096 bta_hf_client_handle_clip(client_cb, number, type);
1097 return buffer;
1098 }
1099
1100 /* in HFP context there is no difference between ccwa and clip */
bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1101 static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb,
1102 char* buffer) {
1103 /* ac to spec 32 chars max, plus \0 here */
1104 char number[33];
1105 uint32_t type = 0;
1106 int res;
1107 int offset = 0;
1108
1109 AT_CHECK_EVENT(buffer, "+CCWA:");
1110
1111 /* there might be something more after %lu but HFP doesn't care */
1112 res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1113 if (res < 2) {
1114 return NULL;
1115 }
1116
1117 if (offset == 0) {
1118 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1119 return NULL;
1120 }
1121
1122 buffer += offset;
1123
1124 AT_SKIP_REST(buffer);
1125
1126 AT_CHECK_RN(buffer);
1127
1128 bta_hf_client_handle_ccwa(client_cb, number, type);
1129 return buffer;
1130 }
1131
bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1132 static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb,
1133 char* buffer) {
1134 uint8_t mode;
1135 /* spec forces 16 chars max, plus \0 here */
1136 char opstr[17];
1137 int res;
1138 int offset = 0;
1139
1140 AT_CHECK_EVENT(buffer, "+COPS:");
1141
1142 /* TODO: Not sure if operator string actually can contain escaped " char
1143 * inside */
1144 res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
1145 if (res < 2) {
1146 return NULL;
1147 }
1148 /* Abort in case offset not set because of format error */
1149 if (offset == 0) {
1150 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1151 return NULL;
1152 }
1153
1154 buffer += offset;
1155
1156 AT_SKIP_REST(buffer);
1157
1158 AT_CHECK_RN(buffer);
1159
1160 bta_hf_client_handle_cops(client_cb, opstr, mode);
1161 // check for OK Response in end
1162 AT_CHECK_EVENT(buffer, "OK");
1163 AT_CHECK_RN(buffer);
1164
1165 bta_hf_client_handle_ok(client_cb);
1166
1167 return buffer;
1168 }
1169
bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1170 static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb,
1171 char* buffer) {
1172 /* HFP only supports phone number as BINP data */
1173 /* phone number is 32 chars plus one for \0*/
1174 char numstr[33];
1175 int res;
1176 int offset = 0;
1177
1178 AT_CHECK_EVENT(buffer, "+BINP:");
1179
1180 res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
1181 if (res < 1) {
1182 return NULL;
1183 }
1184
1185 /* Abort in case offset not set because of format error */
1186 if (offset == 0) {
1187 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1188 return NULL;
1189 }
1190
1191 buffer += offset;
1192
1193 /* some phones might sent type as well, just skip it */
1194 AT_SKIP_REST(buffer);
1195
1196 AT_CHECK_RN(buffer);
1197
1198 bta_hf_client_handle_binp(client_cb, numstr);
1199
1200 // check for OK response in end
1201 AT_CHECK_EVENT(buffer, "OK");
1202 AT_CHECK_RN(buffer);
1203
1204 bta_hf_client_handle_ok(client_cb);
1205
1206 return buffer;
1207 }
1208
bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1209 static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb,
1210 char* buffer) {
1211 uint16_t idx, dir, status, mode, mpty;
1212 char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1213 uint16_t type;
1214 int res;
1215 int offset = 0;
1216
1217 AT_CHECK_EVENT(buffer, "+CLCC:");
1218
1219 res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode,
1220 &mpty, &offset);
1221 if (res < 5) {
1222 return NULL;
1223 }
1224
1225 /* Abort in case offset not set because of format error */
1226 if (offset == 0) {
1227 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1228 return NULL;
1229 }
1230
1231 buffer += offset;
1232 offset = 0;
1233
1234 /* check optional part */
1235 if (*buffer == ',') {
1236 int res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
1237 if (res2 < 0) return NULL;
1238
1239 if (res2 == 0) {
1240 res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
1241 if (res2 < 0) return NULL;
1242
1243 /* numstr is not matched in second attempt, correct this */
1244 res2++;
1245 numstr[0] = '\0';
1246 }
1247
1248 if (res2 >= 2) {
1249 res += res2;
1250 /* Abort in case offset not set because of format error */
1251 if (offset == 0) {
1252 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1253 return NULL;
1254 }
1255
1256 buffer += offset;
1257 }
1258 }
1259
1260 /* Skip any remaing param,as they are not defined by BT HFP spec */
1261 AT_SKIP_REST(buffer);
1262 AT_CHECK_RN(buffer);
1263
1264 if (res > 6) {
1265 /* we also have last two optional parameters */
1266 bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, numstr,
1267 type);
1268 } else {
1269 /* we didn't get the last two parameters */
1270 bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, NULL, 0);
1271 }
1272
1273 // check for OK response in end
1274 AT_CHECK_EVENT(buffer, "OK");
1275 AT_CHECK_RN(buffer);
1276
1277 bta_hf_client_handle_ok(client_cb);
1278 return buffer;
1279 }
1280
bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1281 static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb,
1282 char* buffer) {
1283 char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1284 uint16_t type;
1285 uint16_t service =
1286 0; /* 0 in case this optional parameter is not being sent */
1287 int res;
1288 int offset = 0;
1289
1290 AT_CHECK_EVENT(buffer, "+CNUM:");
1291
1292 res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service,
1293 &offset);
1294 if (res < 0) {
1295 return NULL;
1296 }
1297
1298 if (res == 0) {
1299 res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
1300 if (res < 0) {
1301 return NULL;
1302 }
1303
1304 /* numstr is not matched in second attempt, correct this */
1305 res++;
1306 numstr[0] = '\0';
1307 }
1308
1309 if (res < 3) {
1310 return NULL;
1311 }
1312
1313 /* Abort in case offset not set because of format error */
1314 if (offset == 0) {
1315 APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1316 return NULL;
1317 }
1318
1319 buffer += offset;
1320
1321 AT_CHECK_RN(buffer);
1322
1323 /* service is optional */
1324 if (res == 2) {
1325 bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1326 return buffer;
1327 }
1328
1329 if (service != 4 && service != 5) {
1330 return NULL;
1331 }
1332
1333 bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1334
1335 // check for OK response in end
1336 AT_CHECK_EVENT(buffer, "OK");
1337 AT_CHECK_RN(buffer);
1338
1339 bta_hf_client_handle_ok(client_cb);
1340 return buffer;
1341 }
1342
bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1343 static char* bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB* client_cb,
1344 char* buffer) {
1345 uint16_t code = 0;
1346 int res;
1347 int offset;
1348
1349 AT_CHECK_EVENT(buffer, "+BTRH:");
1350
1351 res = sscanf(buffer, "%hu%n", &code, &offset);
1352 if (res < 1) {
1353 return NULL;
1354 }
1355
1356 buffer += offset;
1357
1358 AT_CHECK_RN(buffer);
1359
1360 bta_hf_client_handle_btrh(client_cb, code);
1361 return buffer;
1362 }
1363
bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1364 static char* bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB* client_cb,
1365 char* buffer) {
1366 AT_CHECK_EVENT(buffer, "BUSY");
1367 AT_CHECK_RN(buffer);
1368
1369 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
1370
1371 return buffer;
1372 }
1373
bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1374 static char* bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB* client_cb,
1375 char* buffer) {
1376 AT_CHECK_EVENT(buffer, "DELAYED");
1377 AT_CHECK_RN(buffer);
1378
1379 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
1380
1381 return buffer;
1382 }
1383
bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1384 static char* bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB* client_cb,
1385 char* buffer) {
1386 AT_CHECK_EVENT(buffer, "NO CARRIER");
1387 AT_CHECK_RN(buffer);
1388
1389 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
1390
1391 return buffer;
1392 }
1393
bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1394 static char* bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB* client_cb,
1395 char* buffer) {
1396 AT_CHECK_EVENT(buffer, "NO ANSWER");
1397 AT_CHECK_RN(buffer);
1398
1399 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
1400
1401 return buffer;
1402 }
1403
bta_hf_client_parse_blacklisted(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1404 static char* bta_hf_client_parse_blacklisted(tBTA_HF_CLIENT_CB* client_cb,
1405 char* buffer) {
1406 AT_CHECK_EVENT(buffer, "BLACKLISTED");
1407 AT_CHECK_RN(buffer);
1408
1409 bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BLACKLISTED, 0);
1410
1411 return buffer;
1412 }
1413
bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1414 static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb,
1415 char* buffer) {
1416 char* start;
1417 char* tmp;
1418
1419 tmp = strstr(buffer, "\r\n");
1420 if (tmp == NULL) {
1421 return NULL;
1422 }
1423
1424 buffer += 2;
1425 start = buffer;
1426
1427 tmp = strstr(buffer, "\r\n");
1428 if (tmp == NULL) {
1429 return NULL;
1430 }
1431
1432 buffer = tmp + 2;
1433
1434 APPL_TRACE_DEBUG("%s: %.*s", __func__, buffer - start - 2, start);
1435
1436 return buffer;
1437 }
1438
1439 /******************************************************************************
1440 * SUPPORTED EVENT MESSAGES
1441 ******************************************************************************/
1442
1443 /* returned values are as follow:
1444 * != NULL && != buf : match and parsed ok
1445 * == NULL : match but parse failed
1446 * != NULL && == buf : no match
1447 */
1448 typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
1449
1450 static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
1451 bta_hf_client_parse_ok, bta_hf_client_parse_error,
1452 bta_hf_client_parse_ring, bta_hf_client_parse_brsf,
1453 bta_hf_client_parse_cind, bta_hf_client_parse_ciev,
1454 bta_hf_client_parse_chld, bta_hf_client_parse_bcs,
1455 bta_hf_client_parse_bsir, bta_hf_client_parse_cmeerror,
1456 bta_hf_client_parse_vgm, bta_hf_client_parse_vgme,
1457 bta_hf_client_parse_vgs, bta_hf_client_parse_vgse,
1458 bta_hf_client_parse_bvra, bta_hf_client_parse_clip,
1459 bta_hf_client_parse_ccwa, bta_hf_client_parse_cops,
1460 bta_hf_client_parse_binp, bta_hf_client_parse_clcc,
1461 bta_hf_client_parse_cnum, bta_hf_client_parse_btrh,
1462 bta_hf_client_parse_busy, bta_hf_client_parse_delayed,
1463 bta_hf_client_parse_no_carrier, bta_hf_client_parse_no_answer,
1464 bta_hf_client_parse_blacklisted, bta_hf_client_skip_unknown};
1465
1466 /* calculate supported event list length */
1467 static const uint16_t bta_hf_client_parser_cb_count =
1468 sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
1469
1470 #ifdef BTA_HF_CLIENT_AT_DUMP
bta_hf_client_dump_at(tBTA_HF_CLIENT_CB * client_cb)1471 static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
1472 char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
1473 char *p1, *p2;
1474
1475 p1 = client_cb->at_cb.buf;
1476 p2 = dump;
1477
1478 while (*p1 != '\0') {
1479 if (*p1 == '\r') {
1480 strlcpy(p2, "<cr>", 4);
1481 p2 += 4;
1482 } else if (*p1 == '\n') {
1483 strlcpy(p2, "<lf>", 4);
1484 p2 += 4;
1485 } else {
1486 *p2 = *p1;
1487 p2++;
1488 }
1489 p1++;
1490 }
1491
1492 *p2 = '\0';
1493
1494 APPL_TRACE_DEBUG("%s: %s", __func__, dump);
1495 }
1496 #endif
1497
bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB * client_cb)1498 static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
1499 char* buf = client_cb->at_cb.buf;
1500
1501 APPL_TRACE_DEBUG("%s", __func__);
1502
1503 #ifdef BTA_HF_CLIENT_AT_DUMP
1504 bta_hf_client_dump_at(client_cb);
1505 #endif
1506
1507 while (*buf != '\0') {
1508 int i;
1509 char* tmp = NULL;
1510
1511 for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
1512 tmp = bta_hf_client_parser_cb[i](client_cb, buf);
1513 if (tmp == NULL) {
1514 APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
1515 tmp = bta_hf_client_skip_unknown(client_cb, buf);
1516 break;
1517 }
1518
1519 /* matched or unknown skipped, if unknown failed tmp is NULL so
1520 this is also handled */
1521 if (tmp != buf) {
1522 buf = tmp;
1523 break;
1524 }
1525 }
1526
1527 /* could not skip unknown (received garbage?)... disconnect */
1528 if (tmp == NULL) {
1529 APPL_TRACE_ERROR(
1530 "HFPCient: could not skip unknown AT event, disconnecting");
1531 bta_hf_client_at_reset(client_cb);
1532
1533 tBTA_HF_CLIENT_DATA msg;
1534 msg.hdr.layer_specific = client_cb->handle;
1535 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1536 return;
1537 }
1538
1539 buf = tmp;
1540 }
1541 }
1542
bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB * client_cb)1543 static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
1544 bool ret = false;
1545 tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
1546
1547 if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
1548 if (at_cb->buf[at_cb->offset - 2] == '\r' &&
1549 at_cb->buf[at_cb->offset - 1] == '\n') {
1550 ret = true;
1551 }
1552 }
1553
1554 APPL_TRACE_DEBUG("%s: %d", __func__, ret);
1555
1556 return ret;
1557 }
1558
bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB * client_cb)1559 static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
1560 memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
1561 client_cb->at_cb.offset = 0;
1562 }
1563
1564 /******************************************************************************
1565 *
1566 * MAIN PARSING FUNCTION
1567 *
1568 *
1569 ******************************************************************************/
bta_hf_client_at_parse(tBTA_HF_CLIENT_CB * client_cb,char * buf,unsigned int len)1570 void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
1571 unsigned int len) {
1572 APPL_TRACE_DEBUG("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset,
1573 len);
1574
1575 if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
1576 char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
1577 unsigned int tmp = client_cb->at_cb.offset;
1578 unsigned int space_left =
1579 BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
1580
1581 APPL_TRACE_DEBUG("%s: overrun, trying to recover", __func__);
1582
1583 /* fill up parser buffer */
1584 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
1585 len -= space_left;
1586 buf += space_left;
1587 client_cb->at_cb.offset += space_left;
1588
1589 /* find end of last complete command before proceeding */
1590 while (!bta_hf_client_check_at_complete(client_cb)) {
1591 if (client_cb->at_cb.offset == 0) {
1592 APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");
1593
1594 bta_hf_client_at_reset(client_cb);
1595
1596 tBTA_HF_CLIENT_DATA msg;
1597 msg.hdr.layer_specific = client_cb->handle;
1598 bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1599 return;
1600 }
1601
1602 client_cb->at_cb.offset--;
1603 }
1604
1605 /* cut buffer to complete AT event and keep cut data */
1606 tmp += space_left - client_cb->at_cb.offset;
1607 memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
1608 client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
1609
1610 /* parse */
1611 bta_hf_client_at_parse_start(client_cb);
1612 bta_hf_client_at_clear_buf(client_cb);
1613
1614 /* recover cut data */
1615 memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
1616 client_cb->at_cb.offset += tmp;
1617 }
1618
1619 memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
1620 client_cb->at_cb.offset += len;
1621
1622 /* If last event is complete, parsing can be started */
1623 if (bta_hf_client_check_at_complete(client_cb)) {
1624 bta_hf_client_at_parse_start(client_cb);
1625 bta_hf_client_at_clear_buf(client_cb);
1626 }
1627 }
1628
bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_FEAT features)1629 void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
1630 tBTA_HF_CLIENT_FEAT features) {
1631 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1632 int at_len;
1633
1634 APPL_TRACE_DEBUG("%s", __func__);
1635
1636 at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
1637 if (at_len < 0) {
1638 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1639 return;
1640 }
1641
1642 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
1643 }
1644
bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB * client_cb)1645 void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
1646 const char* buf;
1647
1648 APPL_TRACE_DEBUG("%s", __func__);
1649
1650 buf = "AT+BAC=1,2\r";
1651
1652 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
1653 }
1654
bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)1655 void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
1656 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1657 int at_len;
1658
1659 APPL_TRACE_DEBUG("%s", __func__);
1660
1661 at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
1662 if (at_len < 0) {
1663 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1664 return;
1665 }
1666
1667 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
1668 }
1669
bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB * client_cb,bool status)1670 void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
1671 const char* buf;
1672 tBTA_HF_CLIENT_AT_CMD cmd;
1673
1674 APPL_TRACE_DEBUG("%s", __func__);
1675
1676 if (status) {
1677 buf = "AT+CIND?\r";
1678 cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
1679 } else {
1680 buf = "AT+CIND=?\r";
1681 cmd = BTA_HF_CLIENT_AT_CIND;
1682 }
1683
1684 bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
1685 }
1686
bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB * client_cb,bool activate)1687 void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1688 const char* buf;
1689
1690 APPL_TRACE_DEBUG("%s", __func__);
1691
1692 if (activate)
1693 buf = "AT+CMER=3,0,0,1\r";
1694 else
1695 buf = "AT+CMER=3,0,0,0\r";
1696
1697 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
1698 }
1699
bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB * client_cb,char cmd,uint32_t idx)1700 void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
1701 uint32_t idx) {
1702 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1703 int at_len;
1704
1705 APPL_TRACE_DEBUG("%s", __func__);
1706
1707 if (idx > 0)
1708 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
1709 else
1710 at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
1711
1712 if (at_len < 0) {
1713 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1714 return;
1715 }
1716
1717 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
1718 }
1719
bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB * client_cb,bool activate)1720 void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1721 const char* buf;
1722
1723 APPL_TRACE_DEBUG("%s", __func__);
1724
1725 if (activate)
1726 buf = "AT+CLIP=1\r";
1727 else
1728 buf = "AT+CLIP=0\r";
1729
1730 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
1731 }
1732
bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB * client_cb,bool activate)1733 void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1734 const char* buf;
1735
1736 APPL_TRACE_DEBUG("%s", __func__);
1737
1738 if (activate)
1739 buf = "AT+CCWA=1\r";
1740 else
1741 buf = "AT+CCWA=0\r";
1742
1743 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
1744 }
1745
bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB * client_cb,bool activate)1746 void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1747 const char* buf;
1748
1749 APPL_TRACE_DEBUG("%s", __func__);
1750
1751 if (activate)
1752 buf = "AT+CMEE=1\r";
1753 else
1754 buf = "AT+CMEE=0\r";
1755
1756 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
1757 }
1758
bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB * client_cb,bool query)1759 void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
1760 const char* buf;
1761
1762 APPL_TRACE_DEBUG("%s", __func__);
1763
1764 if (query)
1765 buf = "AT+COPS?\r";
1766 else
1767 buf = "AT+COPS=3,0\r";
1768
1769 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
1770 }
1771
bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB * client_cb)1772 void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
1773 const char* buf;
1774
1775 APPL_TRACE_DEBUG("%s", __func__);
1776
1777 buf = "AT+CLCC\r";
1778
1779 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
1780 }
1781
bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB * client_cb,bool enable)1782 void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
1783 const char* buf;
1784
1785 APPL_TRACE_DEBUG("%s", __func__);
1786
1787 if (enable)
1788 buf = "AT+BVRA=1\r";
1789 else
1790 buf = "AT+BVRA=0\r";
1791
1792 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
1793 }
1794
bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1795 void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1796 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1797 int at_len;
1798
1799 APPL_TRACE_DEBUG("%s", __func__);
1800
1801 at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
1802 if (at_len < 0) {
1803 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1804 return;
1805 }
1806
1807 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
1808 }
1809
bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1810 void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1811 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1812 int at_len;
1813
1814 APPL_TRACE_DEBUG("%s", __func__);
1815
1816 at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
1817 if (at_len < 0) {
1818 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1819 return;
1820 }
1821
1822 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
1823 }
1824
bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB * client_cb,char * number,uint32_t memory)1825 void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number,
1826 uint32_t memory) {
1827 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1828 int at_len;
1829
1830 APPL_TRACE_DEBUG("%s", __func__);
1831
1832 if (number[0] != '\0') {
1833 at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
1834 } else {
1835 at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
1836 }
1837
1838 if (at_len < 0) {
1839 APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
1840 return;
1841 }
1842
1843 at_len = MIN((size_t)at_len, sizeof(buf));
1844
1845 if (at_len < 0) {
1846 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1847 return;
1848 }
1849 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
1850 }
1851
bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB * client_cb)1852 void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
1853 const char* buf;
1854
1855 APPL_TRACE_DEBUG("%s", __func__);
1856
1857 buf = "AT+BLDN\r";
1858
1859 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
1860 }
1861
bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB * client_cb)1862 void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
1863 const char* buf;
1864
1865 APPL_TRACE_DEBUG("%s", __func__);
1866
1867 buf = "ATA\r";
1868
1869 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
1870 }
1871
bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB * client_cb)1872 void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
1873 const char* buf;
1874
1875 APPL_TRACE_DEBUG("%s", __func__);
1876
1877 buf = "AT+CHUP\r";
1878
1879 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
1880 }
1881
bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB * client_cb,bool query,uint32_t val)1882 void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
1883 uint32_t val) {
1884 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1885 int at_len;
1886
1887 APPL_TRACE_DEBUG("%s", __func__);
1888
1889 if (query) {
1890 at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
1891 } else {
1892 at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
1893 }
1894
1895 if (at_len < 0) {
1896 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1897 return;
1898 }
1899
1900 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
1901 }
1902
bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB * client_cb,char code)1903 void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
1904 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1905 int at_len;
1906
1907 APPL_TRACE_DEBUG("%s", __func__);
1908
1909 at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
1910
1911 if (at_len < 0) {
1912 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1913 return;
1914 }
1915
1916 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
1917 }
1918
bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB * client_cb)1919 void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
1920 const char* buf;
1921
1922 APPL_TRACE_DEBUG("%s", __func__);
1923
1924 buf = "AT+BCC\r";
1925
1926 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
1927 }
1928
bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB * client_cb)1929 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
1930 const char* buf;
1931
1932 APPL_TRACE_DEBUG("%s", __func__);
1933
1934 buf = "AT+CNUM\r";
1935
1936 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
1937 }
1938
bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB * client_cb)1939 void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
1940 const char* buf;
1941
1942 APPL_TRACE_DEBUG("%s", __func__);
1943
1944 if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
1945 APPL_TRACE_ERROR("%s: Remote does not support NREC.", __func__);
1946 return;
1947 }
1948
1949 buf = "AT+NREC=0\r";
1950
1951 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
1952 }
1953
bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB * client_cb,uint32_t action)1954 void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
1955 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1956 int at_len;
1957
1958 APPL_TRACE_DEBUG("%s", __func__);
1959
1960 at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
1961
1962 if (at_len < 0) {
1963 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1964 return;
1965 }
1966
1967 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
1968 }
1969
bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB * client_cb)1970 void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
1971 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1972 int at_len;
1973 int i;
1974
1975 APPL_TRACE_DEBUG("%s", __func__);
1976 if (client_cb->peer_version < HFP_VERSION_1_6) {
1977 APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
1978 return;
1979 }
1980
1981 at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
1982
1983 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
1984 int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
1985
1986 at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
1987 }
1988
1989 buf[at_len - 1] = '\r';
1990
1991 if (at_len < 0) {
1992 APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1993 return;
1994 }
1995
1996 bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
1997 }
1998
bta_hf_client_at_init(tBTA_HF_CLIENT_CB * client_cb)1999 void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
2000 alarm_free(client_cb->at_cb.resp_timer);
2001 alarm_free(client_cb->at_cb.hold_timer);
2002 memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
2003 client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
2004 client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
2005 bta_hf_client_at_reset(client_cb);
2006 }
2007
bta_hf_client_at_reset(tBTA_HF_CLIENT_CB * client_cb)2008 void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
2009 int i;
2010
2011 bta_hf_client_stop_at_resp_timer(client_cb);
2012 bta_hf_client_stop_at_hold_timer(client_cb);
2013
2014 bta_hf_client_clear_queued_at(client_cb);
2015
2016 bta_hf_client_at_clear_buf(client_cb);
2017
2018 for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2019 client_cb->at_cb.indicator_lookup[i] = -1;
2020 }
2021
2022 client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
2023 }
2024
bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA * p_data)2025 void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
2026 tBTA_HF_CLIENT_CB* client_cb =
2027 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
2028 if (!client_cb) {
2029 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
2030 p_data->hdr.layer_specific);
2031 return;
2032 }
2033
2034 tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
2035 char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2036
2037 APPL_TRACE_DEBUG("%s: at cmd: %d", __func__, p_val->uint8_val);
2038 switch (p_val->uint8_val) {
2039 case BTA_HF_CLIENT_AT_CMD_VTS:
2040 bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
2041 break;
2042 case BTA_HF_CLIENT_AT_CMD_BTRH:
2043 bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
2044 break;
2045 case BTA_HF_CLIENT_AT_CMD_CHUP:
2046 bta_hf_client_send_at_chup(client_cb);
2047 break;
2048 case BTA_HF_CLIENT_AT_CMD_CHLD:
2049 /* expects ascii code for command */
2050 bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
2051 p_val->uint32_val2);
2052 break;
2053 case BTA_HF_CLIENT_AT_CMD_BCC:
2054 bta_hf_client_send_at_bcc(client_cb);
2055 break;
2056 case BTA_HF_CLIENT_AT_CMD_CNUM:
2057 bta_hf_client_send_at_cnum(client_cb);
2058 break;
2059 case BTA_HF_CLIENT_AT_CMD_ATA:
2060 bta_hf_client_send_at_ata(client_cb);
2061 break;
2062 case BTA_HF_CLIENT_AT_CMD_COPS:
2063 bta_hf_client_send_at_cops(client_cb, true);
2064 break;
2065 case BTA_HF_CLIENT_AT_CMD_ATD:
2066 bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
2067 break;
2068 case BTA_HF_CLIENT_AT_CMD_VGM:
2069 bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
2070 break;
2071 case BTA_HF_CLIENT_AT_CMD_VGS:
2072 bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
2073 break;
2074 case BTA_HF_CLIENT_AT_CMD_BVRA:
2075 bta_hf_client_send_at_bvra(client_cb,
2076 p_val->uint32_val1 == 0 ? false : true);
2077 break;
2078 case BTA_HF_CLIENT_AT_CMD_CLCC:
2079 bta_hf_client_send_at_clcc(client_cb);
2080 break;
2081 case BTA_HF_CLIENT_AT_CMD_BINP:
2082 bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
2083 break;
2084 case BTA_HF_CLIENT_AT_CMD_BLDN:
2085 bta_hf_client_send_at_bldn(client_cb);
2086 break;
2087 case BTA_HF_CLIENT_AT_CMD_NREC:
2088 bta_hf_client_send_at_nrec(client_cb);
2089 break;
2090 default:
2091 APPL_TRACE_ERROR("Default case");
2092 snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
2093 "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val,
2094 p_val->uint32_val1, p_val->uint32_val2, p_val->str);
2095 APPL_TRACE_ERROR("%s: AT buffer: %s ", __func__, buf);
2096 break;
2097 }
2098 }
2099