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