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 * 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 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 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 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 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 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 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 == false) && 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 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 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 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 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 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 == false) { 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 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 == false) { 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ******************************************************************************/ 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) == false) { 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) == true) { 1624 bta_hf_client_at_parse_start(client_cb); 1625 bta_hf_client_at_clear_buf(client_cb); 1626 } 1627 } 1628 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 == true) { 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 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 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 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 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 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 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 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 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 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