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