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