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