• 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   memset(&evt, 0, sizeof(evt));
730 
731   evt.cnum.service = service;
732   strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
733   evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
734 
735   evt.cnum.bd_addr = client_cb->peer_addr;
736   bta_hf_client_app_callback(BTA_HF_CLIENT_CNUM_EVT, &evt);
737 }
738 
739 /*******************************************************************************
740  *
741  * Function         bta_hf_client_binp
742  *
743  * Description      Send BINP event to application.
744  *
745  *
746  * Returns          void
747  *
748  ******************************************************************************/
bta_hf_client_binp(tBTA_HF_CLIENT_CB * client_cb,char * number)749 void bta_hf_client_binp(tBTA_HF_CLIENT_CB* client_cb, char* number) {
750   tBTA_HF_CLIENT evt;
751 
752   memset(&evt, 0, sizeof(evt));
753 
754   strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
755   evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
756 
757   evt.number.bd_addr = client_cb->peer_addr;
758   bta_hf_client_app_callback(BTA_HF_CLIENT_BINP_EVT, &evt);
759 }
760 
761 /******************************************************************************
762  *
763  *          COMMON AT EVENTS PARSING FUNCTIONS
764  *
765  ******************************************************************************/
766 
767 /* Check if prefix match and skip spaces if any */
768 #define AT_CHECK_EVENT(buf, event)                                             \
769   do {                                                                         \
770     if (strncmp("\r\n" event, buf, sizeof("\r\n" event) - 1) != 0) return buf; \
771     (buf) += sizeof("\r\n" event) - 1;                                         \
772     while (*(buf) == ' ') (buf)++;                                             \
773   } while (0)
774 
775 /* check for <cr><lf> and forward buffer if match */
776 #define AT_CHECK_RN(buf)                                      \
777   do {                                                        \
778     if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) {      \
779       APPL_TRACE_DEBUG("%s: missing end <cr><lf>", __func__); \
780       return NULL;                                            \
781     }                                                         \
782     (buf) += sizeof("\r\n") - 1;                              \
783   } while (0)
784 
785 /* skip rest of AT string up to <cr> */
786 #define AT_SKIP_REST(buf)           \
787   do {                              \
788     while (*(buf) != '\r') (buf)++; \
789   } while (0)
790 
bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB * client_cb,char * buffer)791 static char* bta_hf_client_parse_ok(tBTA_HF_CLIENT_CB* client_cb,
792                                     char* buffer) {
793   AT_CHECK_EVENT(buffer, "OK");
794   AT_CHECK_RN(buffer);
795 
796   bta_hf_client_handle_ok(client_cb);
797 
798   return buffer;
799 }
800 
bta_hf_client_parse_error(tBTA_HF_CLIENT_CB * client_cb,char * buffer)801 static char* bta_hf_client_parse_error(tBTA_HF_CLIENT_CB* client_cb,
802                                        char* buffer) {
803   AT_CHECK_EVENT(buffer, "ERROR");
804   AT_CHECK_RN(buffer);
805 
806   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_ERROR, 0);
807 
808   return buffer;
809 }
810 
bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB * client_cb,char * buffer)811 static char* bta_hf_client_parse_ring(tBTA_HF_CLIENT_CB* client_cb,
812                                       char* buffer) {
813   AT_CHECK_EVENT(buffer, "RING");
814   AT_CHECK_RN(buffer);
815 
816   bta_hf_client_handle_ring(client_cb);
817 
818   return buffer;
819 }
820 
821 /* 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))822 static char* bta_hf_client_parse_uint32(
823     tBTA_HF_CLIENT_CB* client_cb, char* buffer,
824     void (*handler_callback)(tBTA_HF_CLIENT_CB*, uint32_t)) {
825   uint32_t value;
826   int res;
827   int offset;
828 
829   res = sscanf(buffer, "%u%n", &value, &offset);
830   if (res < 1) {
831     return NULL;
832   }
833 
834   buffer += offset;
835 
836   AT_CHECK_RN(buffer);
837 
838   handler_callback(client_cb, value);
839   return buffer;
840 }
841 
bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB * client_cb,char * buffer)842 static char* bta_hf_client_parse_brsf(tBTA_HF_CLIENT_CB* client_cb,
843                                       char* buffer) {
844   AT_CHECK_EVENT(buffer, "+BRSF:");
845 
846   return bta_hf_client_parse_uint32(client_cb, buffer,
847                                     bta_hf_client_handle_brsf);
848 }
849 
bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB * client_cb,char * buffer)850 static char* bta_hf_client_parse_cind_values(tBTA_HF_CLIENT_CB* client_cb,
851                                              char* buffer) {
852   /* value and its position */
853   uint16_t index = 0;
854   uint32_t value = 0;
855 
856   int offset;
857   int res;
858 
859   while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
860     /* decides if its valid index and value, if yes stores it */
861     bta_hf_client_handle_cind_value(client_cb, index, value);
862 
863     buffer += offset;
864 
865     /* check if more values are present */
866     if (*buffer != ',') {
867       break;
868     }
869 
870     index++;
871     buffer++;
872   }
873 
874   if (res > 0) {
875     AT_CHECK_RN(buffer);
876     return buffer;
877   }
878 
879   return NULL;
880 }
881 
bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB * client_cb,char * buffer)882 static char* bta_hf_client_parse_cind_list(tBTA_HF_CLIENT_CB* client_cb,
883                                            char* buffer) {
884   int offset = 0;
885   char name[129];
886   uint32_t min, max;
887   uint32_t index = 0;
888   int res;
889 
890   while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min,
891                        &max, &offset)) > 2) {
892     bta_hf_client_handle_cind_list_item(client_cb, name, min, max, index);
893     if (offset == 0) {
894       APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
895       return NULL;
896     }
897 
898     buffer += offset;
899     index++;
900 
901     if (*buffer != ',') {
902       break;
903     }
904 
905     buffer++;
906   }
907 
908   if (res > 2) {
909     AT_CHECK_RN(buffer);
910     return buffer;
911   }
912 
913   return NULL;
914 }
915 
bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB * client_cb,char * buffer)916 static char* bta_hf_client_parse_cind(tBTA_HF_CLIENT_CB* client_cb,
917                                       char* buffer) {
918   AT_CHECK_EVENT(buffer, "+CIND:");
919 
920   if (*buffer == '(') return bta_hf_client_parse_cind_list(client_cb, buffer);
921 
922   return bta_hf_client_parse_cind_values(client_cb, buffer);
923 }
924 
bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB * client_cb,char * buffer)925 static char* bta_hf_client_parse_chld(tBTA_HF_CLIENT_CB* client_cb,
926                                       char* buffer) {
927   AT_CHECK_EVENT(buffer, "+CHLD:");
928 
929   if (*buffer != '(') {
930     return NULL;
931   }
932 
933   buffer++;
934 
935   while (*buffer != '\0') {
936     if (strncmp("0", buffer, 1) == 0) {
937       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL);
938       buffer++;
939     } else if (strncmp("1x", buffer, 2) == 0) {
940       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_X);
941       buffer += 2;
942     } else if (strncmp("1", buffer, 1) == 0) {
943       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_REL_ACC);
944       buffer++;
945     } else if (strncmp("2x", buffer, 2) == 0) {
946       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_PRIV_X);
947       buffer += 2;
948     } else if (strncmp("2", buffer, 1) == 0) {
949       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_HOLD_ACC);
950       buffer++;
951     } else if (strncmp("3", buffer, 1) == 0) {
952       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE);
953       buffer++;
954     } else if (strncmp("4", buffer, 1) == 0) {
955       bta_hf_client_handle_chld(client_cb, BTA_HF_CLIENT_CHLD_MERGE_DETACH);
956       buffer++;
957     } else {
958       return NULL;
959     }
960 
961     if (*buffer == ',') {
962       buffer++;
963       continue;
964     }
965 
966     if (*buffer == ')') {
967       buffer++;
968       break;
969     }
970 
971     return NULL;
972   }
973 
974   AT_CHECK_RN(buffer);
975 
976   return buffer;
977 }
978 
bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB * client_cb,char * buffer)979 static char* bta_hf_client_parse_ciev(tBTA_HF_CLIENT_CB* client_cb,
980                                       char* buffer) {
981   uint32_t index, value;
982   int res;
983   int offset = 0;
984 
985   AT_CHECK_EVENT(buffer, "+CIEV:");
986 
987   res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
988   if (res < 2) {
989     return NULL;
990   }
991 
992   if (offset == 0) {
993     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
994     return NULL;
995   }
996 
997   buffer += offset;
998 
999   AT_CHECK_RN(buffer);
1000 
1001   bta_hf_client_handle_ciev(client_cb, index, value);
1002   return buffer;
1003 }
1004 
bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1005 static char* bta_hf_client_parse_bcs(tBTA_HF_CLIENT_CB* client_cb,
1006                                      char* buffer) {
1007   AT_CHECK_EVENT(buffer, "+BCS:");
1008 
1009   return bta_hf_client_parse_uint32(client_cb, buffer,
1010                                     bta_hf_client_handle_bcs);
1011 }
1012 
bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1013 static char* bta_hf_client_parse_bsir(tBTA_HF_CLIENT_CB* client_cb,
1014                                       char* buffer) {
1015   AT_CHECK_EVENT(buffer, "+BSIR:");
1016 
1017   return bta_hf_client_parse_uint32(client_cb, buffer,
1018                                     bta_hf_client_handle_bsir);
1019 }
1020 
bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1021 static char* bta_hf_client_parse_cmeerror(tBTA_HF_CLIENT_CB* client_cb,
1022                                           char* buffer) {
1023   AT_CHECK_EVENT(buffer, "+CME ERROR:");
1024 
1025   return bta_hf_client_parse_uint32(client_cb, buffer,
1026                                     bta_hf_client_handle_cmeerror);
1027 }
1028 
bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1029 static char* bta_hf_client_parse_vgm(tBTA_HF_CLIENT_CB* client_cb,
1030                                      char* buffer) {
1031   AT_CHECK_EVENT(buffer, "+VGM:");
1032 
1033   return bta_hf_client_parse_uint32(client_cb, buffer,
1034                                     bta_hf_client_handle_vgm);
1035 }
1036 
bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1037 static char* bta_hf_client_parse_vgme(tBTA_HF_CLIENT_CB* client_cb,
1038                                       char* buffer) {
1039   AT_CHECK_EVENT(buffer, "+VGM=");
1040 
1041   return bta_hf_client_parse_uint32(client_cb, buffer,
1042                                     bta_hf_client_handle_vgm);
1043 }
1044 
bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1045 static char* bta_hf_client_parse_vgs(tBTA_HF_CLIENT_CB* client_cb,
1046                                      char* buffer) {
1047   AT_CHECK_EVENT(buffer, "+VGS:");
1048 
1049   return bta_hf_client_parse_uint32(client_cb, buffer,
1050                                     bta_hf_client_handle_vgs);
1051 }
1052 
bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1053 static char* bta_hf_client_parse_vgse(tBTA_HF_CLIENT_CB* client_cb,
1054                                       char* buffer) {
1055   AT_CHECK_EVENT(buffer, "+VGS=");
1056 
1057   return bta_hf_client_parse_uint32(client_cb, buffer,
1058                                     bta_hf_client_handle_vgs);
1059 }
1060 
bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1061 static char* bta_hf_client_parse_bvra(tBTA_HF_CLIENT_CB* client_cb,
1062                                       char* buffer) {
1063   AT_CHECK_EVENT(buffer, "+BVRA:");
1064 
1065   return bta_hf_client_parse_uint32(client_cb, buffer,
1066                                     bta_hf_client_handle_bvra);
1067 }
1068 
bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1069 static char* bta_hf_client_parse_clip(tBTA_HF_CLIENT_CB* client_cb,
1070                                       char* buffer) {
1071   /* spec forces 32 chars, plus \0 here */
1072   char number[33];
1073   uint32_t type = 0;
1074   int res;
1075   int offset = 0;
1076 
1077   AT_CHECK_EVENT(buffer, "+CLIP:");
1078 
1079   /* there might be something more after %lu but HFP doesn't care */
1080   res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1081   if (res < 2) {
1082     return NULL;
1083   }
1084 
1085   if (offset == 0) {
1086     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1087     return NULL;
1088   }
1089 
1090   buffer += offset;
1091 
1092   AT_SKIP_REST(buffer);
1093 
1094   AT_CHECK_RN(buffer);
1095 
1096   bta_hf_client_handle_clip(client_cb, number, type);
1097   return buffer;
1098 }
1099 
1100 /* in HFP context there is no difference between ccwa and clip */
bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1101 static char* bta_hf_client_parse_ccwa(tBTA_HF_CLIENT_CB* client_cb,
1102                                       char* buffer) {
1103   /* ac to spec 32 chars max, plus \0 here */
1104   char number[33];
1105   uint32_t type = 0;
1106   int res;
1107   int offset = 0;
1108 
1109   AT_CHECK_EVENT(buffer, "+CCWA:");
1110 
1111   /* there might be something more after %lu but HFP doesn't care */
1112   res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
1113   if (res < 2) {
1114     return NULL;
1115   }
1116 
1117   if (offset == 0) {
1118     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1119     return NULL;
1120   }
1121 
1122   buffer += offset;
1123 
1124   AT_SKIP_REST(buffer);
1125 
1126   AT_CHECK_RN(buffer);
1127 
1128   bta_hf_client_handle_ccwa(client_cb, number, type);
1129   return buffer;
1130 }
1131 
bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1132 static char* bta_hf_client_parse_cops(tBTA_HF_CLIENT_CB* client_cb,
1133                                       char* buffer) {
1134   uint8_t mode;
1135   /* spec forces 16 chars max, plus \0 here */
1136   char opstr[17];
1137   int res;
1138   int offset = 0;
1139 
1140   AT_CHECK_EVENT(buffer, "+COPS:");
1141 
1142   /* TODO: Not sure if operator string actually can contain escaped " char
1143    * inside */
1144   res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
1145   if (res < 2) {
1146     return NULL;
1147   }
1148   /* Abort in case offset not set because of format error */
1149   if (offset == 0) {
1150     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1151     return NULL;
1152   }
1153 
1154   buffer += offset;
1155 
1156   AT_SKIP_REST(buffer);
1157 
1158   AT_CHECK_RN(buffer);
1159 
1160   bta_hf_client_handle_cops(client_cb, opstr, mode);
1161   // check for OK Response in end
1162   AT_CHECK_EVENT(buffer, "OK");
1163   AT_CHECK_RN(buffer);
1164 
1165   bta_hf_client_handle_ok(client_cb);
1166 
1167   return buffer;
1168 }
1169 
bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1170 static char* bta_hf_client_parse_binp(tBTA_HF_CLIENT_CB* client_cb,
1171                                       char* buffer) {
1172   /* HFP only supports phone number as BINP data */
1173   /* phone number is 32 chars plus one for \0*/
1174   char numstr[33];
1175   int res;
1176   int offset = 0;
1177 
1178   AT_CHECK_EVENT(buffer, "+BINP:");
1179 
1180   res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
1181   if (res < 1) {
1182     return NULL;
1183   }
1184 
1185   /* Abort in case offset not set because of format error */
1186   if (offset == 0) {
1187     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1188     return NULL;
1189   }
1190 
1191   buffer += offset;
1192 
1193   /* some phones might sent type as well, just skip it */
1194   AT_SKIP_REST(buffer);
1195 
1196   AT_CHECK_RN(buffer);
1197 
1198   bta_hf_client_handle_binp(client_cb, numstr);
1199 
1200   // check for OK response in end
1201   AT_CHECK_EVENT(buffer, "OK");
1202   AT_CHECK_RN(buffer);
1203 
1204   bta_hf_client_handle_ok(client_cb);
1205 
1206   return buffer;
1207 }
1208 
bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1209 static char* bta_hf_client_parse_clcc(tBTA_HF_CLIENT_CB* client_cb,
1210                                       char* buffer) {
1211   uint16_t idx, dir, status, mode, mpty;
1212   char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1213   uint16_t type;
1214   int res;
1215   int offset = 0;
1216 
1217   AT_CHECK_EVENT(buffer, "+CLCC:");
1218 
1219   res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n", &idx, &dir, &status, &mode,
1220                &mpty, &offset);
1221   if (res < 5) {
1222     return NULL;
1223   }
1224 
1225   /* Abort in case offset not set because of format error */
1226   if (offset == 0) {
1227     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1228     return NULL;
1229   }
1230 
1231   buffer += offset;
1232   offset = 0;
1233 
1234   /* check optional part */
1235   if (*buffer == ',') {
1236     int res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
1237     if (res2 < 0) return NULL;
1238 
1239     if (res2 == 0) {
1240       res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
1241       if (res2 < 0) return NULL;
1242 
1243       /* numstr is not matched in second attempt, correct this */
1244       res2++;
1245       numstr[0] = '\0';
1246     }
1247 
1248     if (res2 >= 2) {
1249       res += res2;
1250       /* Abort in case offset not set because of format error */
1251       if (offset == 0) {
1252         APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1253         return NULL;
1254       }
1255 
1256       buffer += offset;
1257     }
1258   }
1259 
1260   /* Skip any remaing param,as they are not defined by BT HFP spec */
1261   AT_SKIP_REST(buffer);
1262   AT_CHECK_RN(buffer);
1263 
1264   if (res > 6) {
1265     /* we also have last two optional parameters */
1266     bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, numstr,
1267                               type);
1268   } else {
1269     /* we didn't get the last two parameters */
1270     bta_hf_client_handle_clcc(client_cb, idx, dir, status, mode, mpty, NULL, 0);
1271   }
1272 
1273   // check for OK response in end
1274   AT_CHECK_EVENT(buffer, "OK");
1275   AT_CHECK_RN(buffer);
1276 
1277   bta_hf_client_handle_ok(client_cb);
1278   return buffer;
1279 }
1280 
bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1281 static char* bta_hf_client_parse_cnum(tBTA_HF_CLIENT_CB* client_cb,
1282                                       char* buffer) {
1283   char numstr[33]; /* spec forces 32 chars, plus one for \0*/
1284   uint16_t type;
1285   uint16_t service =
1286       0; /* 0 in case this optional parameter is not being sent */
1287   int res;
1288   int offset = 0;
1289 
1290   AT_CHECK_EVENT(buffer, "+CNUM:");
1291 
1292   res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service,
1293                &offset);
1294   if (res < 0) {
1295     return NULL;
1296   }
1297 
1298   if (res == 0) {
1299     res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
1300     if (res < 0) {
1301       return NULL;
1302     }
1303 
1304     /* numstr is not matched in second attempt, correct this */
1305     res++;
1306     numstr[0] = '\0';
1307   }
1308 
1309   if (res < 3) {
1310     return NULL;
1311   }
1312 
1313   /* Abort in case offset not set because of format error */
1314   if (offset == 0) {
1315     APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
1316     return NULL;
1317   }
1318 
1319   buffer += offset;
1320 
1321   AT_CHECK_RN(buffer);
1322 
1323   /* service is optional */
1324   if (res == 2) {
1325     bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1326     return buffer;
1327   }
1328 
1329   if (service != 4 && service != 5) {
1330     return NULL;
1331   }
1332 
1333   bta_hf_client_handle_cnum(client_cb, numstr, type, service);
1334 
1335   // check for OK response in end
1336   AT_CHECK_EVENT(buffer, "OK");
1337   AT_CHECK_RN(buffer);
1338 
1339   bta_hf_client_handle_ok(client_cb);
1340   return buffer;
1341 }
1342 
bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1343 static char* bta_hf_client_parse_btrh(tBTA_HF_CLIENT_CB* client_cb,
1344                                       char* buffer) {
1345   uint16_t code = 0;
1346   int res;
1347   int offset;
1348 
1349   AT_CHECK_EVENT(buffer, "+BTRH:");
1350 
1351   res = sscanf(buffer, "%hu%n", &code, &offset);
1352   if (res < 1) {
1353     return NULL;
1354   }
1355 
1356   buffer += offset;
1357 
1358   AT_CHECK_RN(buffer);
1359 
1360   bta_hf_client_handle_btrh(client_cb, code);
1361   return buffer;
1362 }
1363 
bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1364 static char* bta_hf_client_parse_busy(tBTA_HF_CLIENT_CB* client_cb,
1365                                       char* buffer) {
1366   AT_CHECK_EVENT(buffer, "BUSY");
1367   AT_CHECK_RN(buffer);
1368 
1369   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BUSY, 0);
1370 
1371   return buffer;
1372 }
1373 
bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1374 static char* bta_hf_client_parse_delayed(tBTA_HF_CLIENT_CB* client_cb,
1375                                          char* buffer) {
1376   AT_CHECK_EVENT(buffer, "DELAYED");
1377   AT_CHECK_RN(buffer);
1378 
1379   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_DELAY, 0);
1380 
1381   return buffer;
1382 }
1383 
bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1384 static char* bta_hf_client_parse_no_carrier(tBTA_HF_CLIENT_CB* client_cb,
1385                                             char* buffer) {
1386   AT_CHECK_EVENT(buffer, "NO CARRIER");
1387   AT_CHECK_RN(buffer);
1388 
1389   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_CARRIER, 0);
1390 
1391   return buffer;
1392 }
1393 
bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1394 static char* bta_hf_client_parse_no_answer(tBTA_HF_CLIENT_CB* client_cb,
1395                                            char* buffer) {
1396   AT_CHECK_EVENT(buffer, "NO ANSWER");
1397   AT_CHECK_RN(buffer);
1398 
1399   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);
1400 
1401   return buffer;
1402 }
1403 
bta_hf_client_parse_blacklisted(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1404 static char* bta_hf_client_parse_blacklisted(tBTA_HF_CLIENT_CB* client_cb,
1405                                              char* buffer) {
1406   AT_CHECK_EVENT(buffer, "BLACKLISTED");
1407   AT_CHECK_RN(buffer);
1408 
1409   bta_hf_client_handle_error(client_cb, BTA_HF_CLIENT_AT_RESULT_BLACKLISTED, 0);
1410 
1411   return buffer;
1412 }
1413 
bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB * client_cb,char * buffer)1414 static char* bta_hf_client_skip_unknown(tBTA_HF_CLIENT_CB* client_cb,
1415                                         char* buffer) {
1416   char* start;
1417   char* tmp;
1418 
1419   tmp = strstr(buffer, "\r\n");
1420   if (tmp == NULL) {
1421     return NULL;
1422   }
1423 
1424   buffer += 2;
1425   start = buffer;
1426 
1427   tmp = strstr(buffer, "\r\n");
1428   if (tmp == NULL) {
1429     return NULL;
1430   }
1431 
1432   buffer = tmp + 2;
1433 
1434   APPL_TRACE_DEBUG("%s: %.*s", __func__, buffer - start - 2, start);
1435 
1436   return buffer;
1437 }
1438 
1439 /******************************************************************************
1440  *       SUPPORTED EVENT MESSAGES
1441  ******************************************************************************/
1442 
1443 /* returned values are as follow:
1444  * != NULL && != buf  : match and parsed ok
1445  * == NULL            : match but parse failed
1446  * != NULL && == buf  : no match
1447  */
1448 typedef char* (*tBTA_HF_CLIENT_PARSER_CALLBACK)(tBTA_HF_CLIENT_CB*, char*);
1449 
1450 static const tBTA_HF_CLIENT_PARSER_CALLBACK bta_hf_client_parser_cb[] = {
1451     bta_hf_client_parse_ok,          bta_hf_client_parse_error,
1452     bta_hf_client_parse_ring,        bta_hf_client_parse_brsf,
1453     bta_hf_client_parse_cind,        bta_hf_client_parse_ciev,
1454     bta_hf_client_parse_chld,        bta_hf_client_parse_bcs,
1455     bta_hf_client_parse_bsir,        bta_hf_client_parse_cmeerror,
1456     bta_hf_client_parse_vgm,         bta_hf_client_parse_vgme,
1457     bta_hf_client_parse_vgs,         bta_hf_client_parse_vgse,
1458     bta_hf_client_parse_bvra,        bta_hf_client_parse_clip,
1459     bta_hf_client_parse_ccwa,        bta_hf_client_parse_cops,
1460     bta_hf_client_parse_binp,        bta_hf_client_parse_clcc,
1461     bta_hf_client_parse_cnum,        bta_hf_client_parse_btrh,
1462     bta_hf_client_parse_busy,        bta_hf_client_parse_delayed,
1463     bta_hf_client_parse_no_carrier,  bta_hf_client_parse_no_answer,
1464     bta_hf_client_parse_blacklisted, bta_hf_client_skip_unknown};
1465 
1466 /* calculate supported event list length */
1467 static const uint16_t bta_hf_client_parser_cb_count =
1468     sizeof(bta_hf_client_parser_cb) / sizeof(bta_hf_client_parser_cb[0]);
1469 
1470 #ifdef BTA_HF_CLIENT_AT_DUMP
bta_hf_client_dump_at(tBTA_HF_CLIENT_CB * client_cb)1471 static void bta_hf_client_dump_at(tBTA_HF_CLIENT_CB* client_cb) {
1472   char dump[(4 * BTA_HF_CLIENT_AT_PARSER_MAX_LEN) + 1];
1473   char *p1, *p2;
1474 
1475   p1 = client_cb->at_cb.buf;
1476   p2 = dump;
1477 
1478   while (*p1 != '\0') {
1479     if (*p1 == '\r') {
1480       strlcpy(p2, "<cr>", 4);
1481       p2 += 4;
1482     } else if (*p1 == '\n') {
1483       strlcpy(p2, "<lf>", 4);
1484       p2 += 4;
1485     } else {
1486       *p2 = *p1;
1487       p2++;
1488     }
1489     p1++;
1490   }
1491 
1492   *p2 = '\0';
1493 
1494   APPL_TRACE_DEBUG("%s: %s", __func__, dump);
1495 }
1496 #endif
1497 
bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB * client_cb)1498 static void bta_hf_client_at_parse_start(tBTA_HF_CLIENT_CB* client_cb) {
1499   char* buf = client_cb->at_cb.buf;
1500 
1501   APPL_TRACE_DEBUG("%s", __func__);
1502 
1503 #ifdef BTA_HF_CLIENT_AT_DUMP
1504   bta_hf_client_dump_at(client_cb);
1505 #endif
1506 
1507   while (*buf != '\0') {
1508     int i;
1509     char* tmp = NULL;
1510 
1511     for (i = 0; i < bta_hf_client_parser_cb_count; i++) {
1512       tmp = bta_hf_client_parser_cb[i](client_cb, buf);
1513       if (tmp == NULL) {
1514         APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
1515         tmp = bta_hf_client_skip_unknown(client_cb, buf);
1516         break;
1517       }
1518 
1519       /* matched or unknown skipped, if unknown failed tmp is NULL so
1520          this is also handled */
1521       if (tmp != buf) {
1522         buf = tmp;
1523         break;
1524       }
1525     }
1526 
1527     /* could not skip unknown (received garbage?)... disconnect */
1528     if (tmp == NULL) {
1529       APPL_TRACE_ERROR(
1530           "HFPCient: could not skip unknown AT event, disconnecting");
1531       bta_hf_client_at_reset(client_cb);
1532 
1533       tBTA_HF_CLIENT_DATA msg;
1534       msg.hdr.layer_specific = client_cb->handle;
1535       bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1536       return;
1537     }
1538 
1539     buf = tmp;
1540   }
1541 }
1542 
bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB * client_cb)1543 static bool bta_hf_client_check_at_complete(tBTA_HF_CLIENT_CB* client_cb) {
1544   bool ret = false;
1545   tBTA_HF_CLIENT_AT_CB* at_cb = &client_cb->at_cb;
1546 
1547   if (at_cb->offset >= BTA_HF_CLIENT_AT_EVENT_MIN_LEN) {
1548     if (at_cb->buf[at_cb->offset - 2] == '\r' &&
1549         at_cb->buf[at_cb->offset - 1] == '\n') {
1550       ret = true;
1551     }
1552   }
1553 
1554   APPL_TRACE_DEBUG("%s: %d", __func__, ret);
1555 
1556   return ret;
1557 }
1558 
bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB * client_cb)1559 static void bta_hf_client_at_clear_buf(tBTA_HF_CLIENT_CB* client_cb) {
1560   memset(client_cb->at_cb.buf, 0, sizeof(client_cb->at_cb.buf));
1561   client_cb->at_cb.offset = 0;
1562 }
1563 
1564 /******************************************************************************
1565  *
1566  *          MAIN PARSING FUNCTION
1567  *
1568  *
1569  ******************************************************************************/
bta_hf_client_at_parse(tBTA_HF_CLIENT_CB * client_cb,char * buf,unsigned int len)1570 void bta_hf_client_at_parse(tBTA_HF_CLIENT_CB* client_cb, char* buf,
1571                             unsigned int len) {
1572   APPL_TRACE_DEBUG("%s: offset: %u len: %u", __func__, client_cb->at_cb.offset,
1573                    len);
1574 
1575   if (len + client_cb->at_cb.offset > BTA_HF_CLIENT_AT_PARSER_MAX_LEN) {
1576     char tmp_buff[BTA_HF_CLIENT_AT_PARSER_MAX_LEN];
1577     unsigned int tmp = client_cb->at_cb.offset;
1578     unsigned int space_left =
1579         BTA_HF_CLIENT_AT_PARSER_MAX_LEN - client_cb->at_cb.offset;
1580 
1581     APPL_TRACE_DEBUG("%s: overrun, trying to recover", __func__);
1582 
1583     /* fill up parser buffer */
1584     memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, space_left);
1585     len -= space_left;
1586     buf += space_left;
1587     client_cb->at_cb.offset += space_left;
1588 
1589     /* find end of last complete command before proceeding */
1590     while (!bta_hf_client_check_at_complete(client_cb)) {
1591       if (client_cb->at_cb.offset == 0) {
1592         APPL_TRACE_ERROR("HFPClient: AT parser buffer overrun, disconnecting");
1593 
1594         bta_hf_client_at_reset(client_cb);
1595 
1596         tBTA_HF_CLIENT_DATA msg;
1597         msg.hdr.layer_specific = client_cb->handle;
1598         bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
1599         return;
1600       }
1601 
1602       client_cb->at_cb.offset--;
1603     }
1604 
1605     /* cut buffer to complete AT event and keep cut data */
1606     tmp += space_left - client_cb->at_cb.offset;
1607     memcpy(tmp_buff, client_cb->at_cb.buf + client_cb->at_cb.offset, tmp);
1608     client_cb->at_cb.buf[client_cb->at_cb.offset] = '\0';
1609 
1610     /* parse */
1611     bta_hf_client_at_parse_start(client_cb);
1612     bta_hf_client_at_clear_buf(client_cb);
1613 
1614     /* recover cut data */
1615     memcpy(client_cb->at_cb.buf, tmp_buff, tmp);
1616     client_cb->at_cb.offset += tmp;
1617   }
1618 
1619   memcpy(client_cb->at_cb.buf + client_cb->at_cb.offset, buf, len);
1620   client_cb->at_cb.offset += len;
1621 
1622   /* If last event is complete, parsing can be started */
1623   if (bta_hf_client_check_at_complete(client_cb)) {
1624     bta_hf_client_at_parse_start(client_cb);
1625     bta_hf_client_at_clear_buf(client_cb);
1626   }
1627 }
1628 
bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB * client_cb,tBTA_HF_CLIENT_FEAT features)1629 void bta_hf_client_send_at_brsf(tBTA_HF_CLIENT_CB* client_cb,
1630                                 tBTA_HF_CLIENT_FEAT features) {
1631   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1632   int at_len;
1633 
1634   APPL_TRACE_DEBUG("%s", __func__);
1635 
1636   at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", features);
1637   if (at_len < 0) {
1638     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1639     return;
1640   }
1641 
1642   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BRSF, buf, at_len);
1643 }
1644 
bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB * client_cb)1645 void bta_hf_client_send_at_bac(tBTA_HF_CLIENT_CB* client_cb) {
1646   const char* buf;
1647 
1648   APPL_TRACE_DEBUG("%s", __func__);
1649 
1650   buf = "AT+BAC=1,2\r";
1651 
1652   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BAC, buf, strlen(buf));
1653 }
1654 
bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB * client_cb,uint32_t codec)1655 void bta_hf_client_send_at_bcs(tBTA_HF_CLIENT_CB* client_cb, uint32_t codec) {
1656   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1657   int at_len;
1658 
1659   APPL_TRACE_DEBUG("%s", __func__);
1660 
1661   at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
1662   if (at_len < 0) {
1663     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1664     return;
1665   }
1666 
1667   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCS, buf, at_len);
1668 }
1669 
bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB * client_cb,bool status)1670 void bta_hf_client_send_at_cind(tBTA_HF_CLIENT_CB* client_cb, bool status) {
1671   const char* buf;
1672   tBTA_HF_CLIENT_AT_CMD cmd;
1673 
1674   APPL_TRACE_DEBUG("%s", __func__);
1675 
1676   if (status) {
1677     buf = "AT+CIND?\r";
1678     cmd = BTA_HF_CLIENT_AT_CIND_STATUS;
1679   } else {
1680     buf = "AT+CIND=?\r";
1681     cmd = BTA_HF_CLIENT_AT_CIND;
1682   }
1683 
1684   bta_hf_client_send_at(client_cb, cmd, buf, strlen(buf));
1685 }
1686 
bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB * client_cb,bool activate)1687 void bta_hf_client_send_at_cmer(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1688   const char* buf;
1689 
1690   APPL_TRACE_DEBUG("%s", __func__);
1691 
1692   if (activate)
1693     buf = "AT+CMER=3,0,0,1\r";
1694   else
1695     buf = "AT+CMER=3,0,0,0\r";
1696 
1697   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMER, buf, strlen(buf));
1698 }
1699 
bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB * client_cb,char cmd,uint32_t idx)1700 void bta_hf_client_send_at_chld(tBTA_HF_CLIENT_CB* client_cb, char cmd,
1701                                 uint32_t idx) {
1702   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1703   int at_len;
1704 
1705   APPL_TRACE_DEBUG("%s", __func__);
1706 
1707   if (idx > 0)
1708     at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c%u\r", cmd, idx);
1709   else
1710     at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
1711 
1712   if (at_len < 0) {
1713     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1714     return;
1715   }
1716 
1717   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHLD, buf, at_len);
1718 }
1719 
bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB * client_cb,bool activate)1720 void bta_hf_client_send_at_clip(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1721   const char* buf;
1722 
1723   APPL_TRACE_DEBUG("%s", __func__);
1724 
1725   if (activate)
1726     buf = "AT+CLIP=1\r";
1727   else
1728     buf = "AT+CLIP=0\r";
1729 
1730   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLIP, buf, strlen(buf));
1731 }
1732 
bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB * client_cb,bool activate)1733 void bta_hf_client_send_at_ccwa(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1734   const char* buf;
1735 
1736   APPL_TRACE_DEBUG("%s", __func__);
1737 
1738   if (activate)
1739     buf = "AT+CCWA=1\r";
1740   else
1741     buf = "AT+CCWA=0\r";
1742 
1743   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CCWA, buf, strlen(buf));
1744 }
1745 
bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB * client_cb,bool activate)1746 void bta_hf_client_send_at_cmee(tBTA_HF_CLIENT_CB* client_cb, bool activate) {
1747   const char* buf;
1748 
1749   APPL_TRACE_DEBUG("%s", __func__);
1750 
1751   if (activate)
1752     buf = "AT+CMEE=1\r";
1753   else
1754     buf = "AT+CMEE=0\r";
1755 
1756   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CMEE, buf, strlen(buf));
1757 }
1758 
bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB * client_cb,bool query)1759 void bta_hf_client_send_at_cops(tBTA_HF_CLIENT_CB* client_cb, bool query) {
1760   const char* buf;
1761 
1762   APPL_TRACE_DEBUG("%s", __func__);
1763 
1764   if (query)
1765     buf = "AT+COPS?\r";
1766   else
1767     buf = "AT+COPS=3,0\r";
1768 
1769   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_COPS, buf, strlen(buf));
1770 }
1771 
bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB * client_cb)1772 void bta_hf_client_send_at_clcc(tBTA_HF_CLIENT_CB* client_cb) {
1773   const char* buf;
1774 
1775   APPL_TRACE_DEBUG("%s", __func__);
1776 
1777   buf = "AT+CLCC\r";
1778 
1779   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CLCC, buf, strlen(buf));
1780 }
1781 
bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB * client_cb,bool enable)1782 void bta_hf_client_send_at_bvra(tBTA_HF_CLIENT_CB* client_cb, bool enable) {
1783   const char* buf;
1784 
1785   APPL_TRACE_DEBUG("%s", __func__);
1786 
1787   if (enable)
1788     buf = "AT+BVRA=1\r";
1789   else
1790     buf = "AT+BVRA=0\r";
1791 
1792   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BVRA, buf, strlen(buf));
1793 }
1794 
bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1795 void bta_hf_client_send_at_vgs(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1796   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1797   int at_len;
1798 
1799   APPL_TRACE_DEBUG("%s", __func__);
1800 
1801   at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
1802   if (at_len < 0) {
1803     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1804     return;
1805   }
1806 
1807   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGS, buf, at_len);
1808 }
1809 
bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB * client_cb,uint32_t volume)1810 void bta_hf_client_send_at_vgm(tBTA_HF_CLIENT_CB* client_cb, uint32_t volume) {
1811   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1812   int at_len;
1813 
1814   APPL_TRACE_DEBUG("%s", __func__);
1815 
1816   at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
1817   if (at_len < 0) {
1818     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1819     return;
1820   }
1821 
1822   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VGM, buf, at_len);
1823 }
1824 
bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB * client_cb,char * number,uint32_t memory)1825 void bta_hf_client_send_at_atd(tBTA_HF_CLIENT_CB* client_cb, char* number,
1826                                uint32_t memory) {
1827   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1828   int at_len;
1829 
1830   APPL_TRACE_DEBUG("%s", __func__);
1831 
1832   if (number[0] != '\0') {
1833     at_len = snprintf(buf, sizeof(buf), "ATD%s;\r", number);
1834   } else {
1835     at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
1836   }
1837 
1838   if (at_len < 0) {
1839     APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
1840     return;
1841   }
1842 
1843   at_len = MIN((size_t)at_len, sizeof(buf));
1844 
1845   if (at_len < 0) {
1846     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1847     return;
1848   }
1849   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATD, buf, at_len);
1850 }
1851 
bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB * client_cb)1852 void bta_hf_client_send_at_bldn(tBTA_HF_CLIENT_CB* client_cb) {
1853   const char* buf;
1854 
1855   APPL_TRACE_DEBUG("%s", __func__);
1856 
1857   buf = "AT+BLDN\r";
1858 
1859   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BLDN, buf, strlen(buf));
1860 }
1861 
bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB * client_cb)1862 void bta_hf_client_send_at_ata(tBTA_HF_CLIENT_CB* client_cb) {
1863   const char* buf;
1864 
1865   APPL_TRACE_DEBUG("%s", __func__);
1866 
1867   buf = "ATA\r";
1868 
1869   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_ATA, buf, strlen(buf));
1870 }
1871 
bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB * client_cb)1872 void bta_hf_client_send_at_chup(tBTA_HF_CLIENT_CB* client_cb) {
1873   const char* buf;
1874 
1875   APPL_TRACE_DEBUG("%s", __func__);
1876 
1877   buf = "AT+CHUP\r";
1878 
1879   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CHUP, buf, strlen(buf));
1880 }
1881 
bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB * client_cb,bool query,uint32_t val)1882 void bta_hf_client_send_at_btrh(tBTA_HF_CLIENT_CB* client_cb, bool query,
1883                                 uint32_t val) {
1884   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1885   int at_len;
1886 
1887   APPL_TRACE_DEBUG("%s", __func__);
1888 
1889   if (query) {
1890     at_len = snprintf(buf, sizeof(buf), "AT+BTRH?\r");
1891   } else {
1892     at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
1893   }
1894 
1895   if (at_len < 0) {
1896     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1897     return;
1898   }
1899 
1900   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BTRH, buf, at_len);
1901 }
1902 
bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB * client_cb,char code)1903 void bta_hf_client_send_at_vts(tBTA_HF_CLIENT_CB* client_cb, char code) {
1904   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1905   int at_len;
1906 
1907   APPL_TRACE_DEBUG("%s", __func__);
1908 
1909   at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
1910 
1911   if (at_len < 0) {
1912     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1913     return;
1914   }
1915 
1916   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_VTS, buf, at_len);
1917 }
1918 
bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB * client_cb)1919 void bta_hf_client_send_at_bcc(tBTA_HF_CLIENT_CB* client_cb) {
1920   const char* buf;
1921 
1922   APPL_TRACE_DEBUG("%s", __func__);
1923 
1924   buf = "AT+BCC\r";
1925 
1926   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
1927 }
1928 
bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB * client_cb)1929 void bta_hf_client_send_at_cnum(tBTA_HF_CLIENT_CB* client_cb) {
1930   const char* buf;
1931 
1932   APPL_TRACE_DEBUG("%s", __func__);
1933 
1934   buf = "AT+CNUM\r";
1935 
1936   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_CNUM, buf, strlen(buf));
1937 }
1938 
bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB * client_cb)1939 void bta_hf_client_send_at_nrec(tBTA_HF_CLIENT_CB* client_cb) {
1940   const char* buf;
1941 
1942   APPL_TRACE_DEBUG("%s", __func__);
1943 
1944   if (!(client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_ECNR)) {
1945     APPL_TRACE_ERROR("%s: Remote does not support NREC.", __func__);
1946     return;
1947   }
1948 
1949   buf = "AT+NREC=0\r";
1950 
1951   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_NREC, buf, strlen(buf));
1952 }
1953 
bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB * client_cb,uint32_t action)1954 void bta_hf_client_send_at_binp(tBTA_HF_CLIENT_CB* client_cb, uint32_t action) {
1955   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1956   int at_len;
1957 
1958   APPL_TRACE_DEBUG("%s", __func__);
1959 
1960   at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
1961 
1962   if (at_len < 0) {
1963     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1964     return;
1965   }
1966 
1967   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BINP, buf, at_len);
1968 }
1969 
bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB * client_cb)1970 void bta_hf_client_send_at_bia(tBTA_HF_CLIENT_CB* client_cb) {
1971   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
1972   int at_len;
1973   int i;
1974 
1975   APPL_TRACE_DEBUG("%s", __func__);
1976   if (client_cb->peer_version < HFP_VERSION_1_6) {
1977     APPL_TRACE_DEBUG("Remote does not Support AT+BIA");
1978     return;
1979   }
1980 
1981   at_len = snprintf(buf, sizeof(buf), "AT+BIA=");
1982 
1983   for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
1984     int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
1985 
1986     at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
1987   }
1988 
1989   buf[at_len - 1] = '\r';
1990 
1991   if (at_len < 0) {
1992     APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
1993     return;
1994   }
1995 
1996   bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BIA, buf, at_len);
1997 }
1998 
bta_hf_client_at_init(tBTA_HF_CLIENT_CB * client_cb)1999 void bta_hf_client_at_init(tBTA_HF_CLIENT_CB* client_cb) {
2000   alarm_free(client_cb->at_cb.resp_timer);
2001   alarm_free(client_cb->at_cb.hold_timer);
2002   memset(&(client_cb->at_cb), 0, sizeof(tBTA_HF_CLIENT_AT_CB));
2003   client_cb->at_cb.resp_timer = alarm_new("bta_hf_client.scb_at_resp_timer");
2004   client_cb->at_cb.hold_timer = alarm_new("bta_hf_client.scb_at_hold_timer");
2005   bta_hf_client_at_reset(client_cb);
2006 }
2007 
bta_hf_client_at_reset(tBTA_HF_CLIENT_CB * client_cb)2008 void bta_hf_client_at_reset(tBTA_HF_CLIENT_CB* client_cb) {
2009   int i;
2010 
2011   bta_hf_client_stop_at_resp_timer(client_cb);
2012   bta_hf_client_stop_at_hold_timer(client_cb);
2013 
2014   bta_hf_client_clear_queued_at(client_cb);
2015 
2016   bta_hf_client_at_clear_buf(client_cb);
2017 
2018   for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
2019     client_cb->at_cb.indicator_lookup[i] = -1;
2020   }
2021 
2022   client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
2023 }
2024 
bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA * p_data)2025 void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA* p_data) {
2026   tBTA_HF_CLIENT_CB* client_cb =
2027       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
2028   if (!client_cb) {
2029     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
2030                      p_data->hdr.layer_specific);
2031     return;
2032   }
2033 
2034   tBTA_HF_CLIENT_DATA_VAL* p_val = (tBTA_HF_CLIENT_DATA_VAL*)p_data;
2035   char buf[BTA_HF_CLIENT_AT_MAX_LEN];
2036 
2037   APPL_TRACE_DEBUG("%s: at cmd: %d", __func__, p_val->uint8_val);
2038   switch (p_val->uint8_val) {
2039     case BTA_HF_CLIENT_AT_CMD_VTS:
2040       bta_hf_client_send_at_vts(client_cb, (char)p_val->uint32_val1);
2041       break;
2042     case BTA_HF_CLIENT_AT_CMD_BTRH:
2043       bta_hf_client_send_at_btrh(client_cb, false, p_val->uint32_val1);
2044       break;
2045     case BTA_HF_CLIENT_AT_CMD_CHUP:
2046       bta_hf_client_send_at_chup(client_cb);
2047       break;
2048     case BTA_HF_CLIENT_AT_CMD_CHLD:
2049       /* expects ascii code for command */
2050       bta_hf_client_send_at_chld(client_cb, '0' + p_val->uint32_val1,
2051                                  p_val->uint32_val2);
2052       break;
2053     case BTA_HF_CLIENT_AT_CMD_BCC:
2054       bta_hf_client_send_at_bcc(client_cb);
2055       break;
2056     case BTA_HF_CLIENT_AT_CMD_CNUM:
2057       bta_hf_client_send_at_cnum(client_cb);
2058       break;
2059     case BTA_HF_CLIENT_AT_CMD_ATA:
2060       bta_hf_client_send_at_ata(client_cb);
2061       break;
2062     case BTA_HF_CLIENT_AT_CMD_COPS:
2063       bta_hf_client_send_at_cops(client_cb, true);
2064       break;
2065     case BTA_HF_CLIENT_AT_CMD_ATD:
2066       bta_hf_client_send_at_atd(client_cb, p_val->str, p_val->uint32_val1);
2067       break;
2068     case BTA_HF_CLIENT_AT_CMD_VGM:
2069       bta_hf_client_send_at_vgm(client_cb, p_val->uint32_val1);
2070       break;
2071     case BTA_HF_CLIENT_AT_CMD_VGS:
2072       bta_hf_client_send_at_vgs(client_cb, p_val->uint32_val1);
2073       break;
2074     case BTA_HF_CLIENT_AT_CMD_BVRA:
2075       bta_hf_client_send_at_bvra(client_cb,
2076                                  p_val->uint32_val1 == 0 ? false : true);
2077       break;
2078     case BTA_HF_CLIENT_AT_CMD_CLCC:
2079       bta_hf_client_send_at_clcc(client_cb);
2080       break;
2081     case BTA_HF_CLIENT_AT_CMD_BINP:
2082       bta_hf_client_send_at_binp(client_cb, p_val->uint32_val1);
2083       break;
2084     case BTA_HF_CLIENT_AT_CMD_BLDN:
2085       bta_hf_client_send_at_bldn(client_cb);
2086       break;
2087     case BTA_HF_CLIENT_AT_CMD_NREC:
2088       bta_hf_client_send_at_nrec(client_cb);
2089       break;
2090     default:
2091       APPL_TRACE_ERROR("Default case");
2092       snprintf(buf, BTA_HF_CLIENT_AT_MAX_LEN,
2093                "Cmd %d 1st arg %u 2nd arg %u string arg %s", p_val->uint8_val,
2094                p_val->uint32_val1, p_val->uint32_val2, p_val->str);
2095       APPL_TRACE_ERROR("%s: AT buffer: %s ", __func__, buf);
2096       break;
2097   }
2098 }
2099