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