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