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