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