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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ******************************************************************************/ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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