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