1 /* 2 * Copyright 2012 The Android Open Source Project 3 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 4 * Not a Contribution. 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 * 21 * Filename: bt_vendor_qcom.c 22 * 23 * Description: vendor specific library implementation 24 * 25 ******************************************************************************/ 26 27 #define LOG_TAG "bt_vendor" 28 #define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr" 29 30 #include <utils/Log.h> 31 #include <cutils/properties.h> 32 #include <fcntl.h> 33 #include <termios.h> 34 #include "bt_vendor_qcom.h" 35 #include "hci_uart.h" 36 #include "hci_smd.h" 37 #include <sys/socket.h> 38 #include <cutils/sockets.h> 39 #include <linux/un.h> 40 #include "bt_vendor_persist.h" 41 #include "hw_rome.h" 42 #include "bt_vendor_lib.h" 43 #define WAIT_TIMEOUT 200000 44 #define BT_VND_OP_GET_LINESPEED 12 45 46 #ifdef PANIC_ON_SOC_CRASH 47 #define BT_VND_FILTER_START "wc_transport.start_root" 48 #else 49 #define BT_VND_FILTER_START "wc_transport.start_hci" 50 #endif 51 52 #define CMD_TIMEOUT 0x22 53 54 static void wait_for_patch_download(bool is_ant_req); 55 static bool is_debug_force_special_bytes(void); 56 57 /****************************************************************************** 58 ** Externs 59 ******************************************************************************/ 60 extern int hw_config(int nState); 61 62 extern int is_hw_ready(); 63 extern int rome_soc_init(int fd, char *bdaddr); 64 extern int check_embedded_mode(int fd); 65 extern int rome_get_addon_feature_list(int fd); 66 extern int rome_ver; 67 extern int enable_controller_log(int fd, unsigned char req); 68 /****************************************************************************** 69 ** Variables 70 ******************************************************************************/ 71 int pFd[2] = {0,}; 72 #ifdef BT_SOC_TYPE_ROME 73 int ant_fd; 74 #endif 75 bt_vendor_callbacks_t *bt_vendor_cbacks = NULL; 76 uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 77 static int btSocType = BT_SOC_DEFAULT; 78 static int rfkill_id = -1; 79 static char *rfkill_state = NULL; 80 bool enable_extldo = FALSE; 81 82 int userial_clock_operation(int fd, int cmd); 83 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti); 84 int rome_soc_init(int fd, char *bdaddr); 85 int userial_vendor_get_baud(void); 86 int readTrpState(); 87 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity); 88 89 static const tUSERIAL_CFG userial_init_cfg = 90 { 91 (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), 92 USERIAL_BAUD_115200 93 }; 94 95 #if (HW_NEED_END_WITH_HCI_RESET == TRUE) 96 void hw_epilog_process(void); 97 #endif 98 99 #ifdef WIFI_BT_STATUS_SYNC 100 #include <string.h> 101 #include <errno.h> 102 #include <dlfcn.h> 103 #include "cutils/properties.h" 104 105 static const char WIFI_PROP_NAME[] = "wlan.driver.status"; 106 static const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl"; 107 static const char BT_STATUS_NAME[] = "bluetooth.enabled"; 108 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl"; 109 110 #define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock" 111 int isInit=0; 112 #endif /* WIFI_BT_STATUS_SYNC */ 113 bool is_soc_initialized(void); 114 115 /****************************************************************************** 116 ** Local type definitions 117 ******************************************************************************/ 118 119 120 /****************************************************************************** 121 ** Functions 122 ******************************************************************************/ 123 #ifdef WIFI_BT_STATUS_SYNC 124 int bt_semaphore_create(void) 125 { 126 int fd; 127 128 fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY); 129 130 if (fd < 0) 131 ALOGE("can't create file\n"); 132 133 return fd; 134 } 135 136 int bt_semaphore_get(int fd) 137 { 138 int ret; 139 140 if (fd < 0) 141 return -1; 142 143 ret = flock(fd, LOCK_EX); 144 if (ret != 0) { 145 ALOGE("can't hold lock: %s\n", strerror(errno)); 146 return -1; 147 } 148 149 return ret; 150 } 151 152 int bt_semaphore_release(int fd) 153 { 154 int ret; 155 156 if (fd < 0) 157 return -1; 158 159 ret = flock(fd, LOCK_UN); 160 if (ret != 0) { 161 ALOGE("can't release lock: %s\n", strerror(errno)); 162 return -1; 163 } 164 165 return ret; 166 } 167 168 int bt_semaphore_destroy(int fd) 169 { 170 if (fd < 0) 171 return -1; 172 173 return close (fd); 174 } 175 176 int bt_wait_for_service_done(void) 177 { 178 char service_status[PROPERTY_VALUE_MAX]; 179 int count = 30; 180 181 ALOGE("%s: check\n", __func__); 182 183 /* wait for service done */ 184 while (count-- > 0) { 185 property_get(WIFI_SERVICE_PROP, service_status, NULL); 186 187 if (strcmp(service_status, "") != 0) { 188 usleep(200000); 189 } else { 190 break; 191 } 192 } 193 194 return 0; 195 } 196 197 #endif /* WIFI_BT_STATUS_SYNC */ 198 199 /** Get Bluetooth SoC type from system setting */ 200 static int get_bt_soc_type() 201 { 202 int ret = 0; 203 char bt_soc_type[PROPERTY_VALUE_MAX]; 204 205 ALOGI("bt-vendor : get_bt_soc_type"); 206 207 ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL); 208 if (ret != 0) { 209 ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type); 210 if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) { 211 return BT_SOC_ROME; 212 } 213 else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) { 214 return BT_SOC_AR3K; 215 } 216 else { 217 ALOGI("qcom.bluetooth.soc not set, so using default.\n"); 218 return BT_SOC_DEFAULT; 219 } 220 } 221 else { 222 ALOGE("%s: Failed to get soc type", __FUNCTION__); 223 ret = BT_SOC_DEFAULT; 224 } 225 226 return ret; 227 } 228 229 bool can_perform_action(char action) { 230 bool can_perform = false; 231 char ref_count[PROPERTY_VALUE_MAX]; 232 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 233 int value, ret; 234 235 property_get("wc_transport.ref_count", ref_count, "0"); 236 237 value = atoi(ref_count); 238 ALOGV("%s: ref_count: %s\n",__func__, ref_count); 239 240 if(action == '1') { 241 ALOGV("%s: on : value is: %d", __func__, value); 242 if(value == 1) 243 { 244 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 245 if((is_soc_initialized() == true) || (strcmp(inProgress,"null") != 0)) 246 { 247 value++; 248 ALOGV("%s: on : value is incremented to : %d", __func__, value); 249 } 250 } 251 else 252 { 253 value++; 254 } 255 256 if (value == 1) 257 can_perform = true; 258 else if (value > 2) 259 return false; 260 } 261 else { 262 ALOGV("%s: off : value is: %d", __func__, value); 263 value--; 264 if (value == 0) 265 can_perform = true; 266 else if (value < 0) 267 return false; 268 } 269 270 snprintf(ref_count, 3, "%d", value); 271 ALOGV("%s: updated ref_count is: %s", __func__, ref_count); 272 273 ret = property_set("wc_transport.ref_count", ref_count); 274 if (ret < 0) { 275 ALOGE("%s: Error while updating property: %d\n", __func__, ret); 276 return false; 277 } 278 ALOGV("%s returning %d", __func__, can_perform); 279 return can_perform; 280 } 281 282 void stop_hci_filter() { 283 char value[PROPERTY_VALUE_MAX] = {'\0'}; 284 ALOGV("%s: Entry ", __func__); 285 286 property_get(BT_VND_FILTER_START, value, "false"); 287 288 if (strcmp(value, "false") == 0) { 289 ALOGI("%s: hci_filter has been stopped already", __func__); 290 // return; 291 } 292 293 property_set(BT_VND_FILTER_START, "false"); 294 property_set("wc_transport.hci_filter_status", "0"); 295 ALOGV("%s: Exit ", __func__); 296 } 297 298 void start_hci_filter() { 299 ALOGV("%s: Entry ", __func__); 300 int i, init_success = 0; 301 char value[PROPERTY_VALUE_MAX] = {'\0'}; 302 303 property_get(BT_VND_FILTER_START, value, false); 304 305 if (strcmp(value, "true") == 0) { 306 ALOGI("%s: hci_filter has been started already", __func__); 307 return; 308 } 309 310 property_set("wc_transport.hci_filter_status", "0"); 311 property_set(BT_VND_FILTER_START, "true"); 312 313 ALOGV("%s: %s set to true ", __func__, BT_VND_FILTER_START ); 314 315 //sched_yield(); 316 for(i=0; i<45; i++) { 317 property_get("wc_transport.hci_filter_status", value, "0"); 318 if (strcmp(value, "1") == 0) { 319 init_success = 1; 320 break; 321 } else { 322 usleep(WAIT_TIMEOUT); 323 } 324 } 325 ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i); 326 327 ALOGV("%s: Exit ", __func__); 328 } 329 330 /** Bluetooth Controller power up or shutdown */ 331 static int bt_powerup(int en ) 332 { 333 char rfkill_type[64], *enable_ldo_path = NULL; 334 char type[16], enable_ldo[6]; 335 int fd, size, i, ret, fd_ldo; 336 337 char disable[PROPERTY_VALUE_MAX]; 338 char state; 339 char on = (en)?'1':'0'; 340 341 #ifdef WIFI_BT_STATUS_SYNC 342 char wifi_status[PROPERTY_VALUE_MAX]; 343 int lock_fd; 344 #endif /*WIFI_BT_STATUS_SYNC*/ 345 346 ALOGI("bt_powerup: %c", on); 347 348 /* Check if rfkill has been disabled */ 349 ret = property_get("ro.rfkilldisabled", disable, "0"); 350 if (!ret ){ 351 ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret); 352 return -1; 353 } 354 /* In case rfkill disabled, then no control power*/ 355 if (strcmp(disable, "1") == 0) { 356 ALOGI("ro.rfkilldisabled : %s", disable); 357 return -1; 358 } 359 360 #ifdef WIFI_BT_STATUS_SYNC 361 lock_fd = bt_semaphore_create(); 362 bt_semaphore_get(lock_fd); 363 bt_wait_for_service_done(); 364 #endif 365 366 /* Assign rfkill_id and find bluetooth rfkill state path*/ 367 for(i=0;(rfkill_id == -1) && (rfkill_state == NULL);i++) 368 { 369 snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i); 370 if ((fd = open(rfkill_type, O_RDONLY)) < 0) 371 { 372 ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno); 373 374 #ifdef WIFI_BT_STATUS_SYNC 375 bt_semaphore_release(lock_fd); 376 bt_semaphore_destroy(lock_fd); 377 #endif 378 return -1; 379 } 380 381 size = read(fd, &type, sizeof(type)); 382 close(fd); 383 384 if ((size >= 9) && !memcmp(type, "bluetooth", 9)) 385 { 386 asprintf(&rfkill_state, "/sys/class/rfkill/rfkill%d/state", rfkill_id = i); 387 break; 388 } 389 } 390 391 /* Get rfkill State to control */ 392 if (rfkill_state != NULL) 393 { 394 if ((fd = open(rfkill_state, O_RDWR)) < 0) 395 { 396 ALOGE("open(%s) for write failed: %s (%d)",rfkill_state, strerror(errno), errno); 397 #ifdef WIFI_BT_STATUS_SYNC 398 bt_semaphore_release(lock_fd); 399 bt_semaphore_destroy(lock_fd); 400 #endif 401 402 return -1; 403 } 404 } 405 #ifdef BT_SOC_TYPE_ROME 406 if(can_perform_action(on) == false) { 407 ALOGE("%s:can't perform action as it is being used by other clients", __func__); 408 #ifdef WIFI_BT_STATUS_SYNC 409 bt_semaphore_release(lock_fd); 410 bt_semaphore_destroy(lock_fd); 411 #endif 412 goto done; 413 } 414 #endif 415 ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", rfkill_id); 416 if( (ret < 0 ) || (enable_ldo_path == NULL) ) 417 { 418 ALOGE("Memory Allocation failure"); 419 return -1; 420 } 421 if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) { 422 ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 423 return -1; 424 } 425 size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo)); 426 close(fd_ldo); 427 if (size <= 0) { 428 ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 429 return -1; 430 } 431 if (!memcmp(enable_ldo, "true", 4)) { 432 ALOGI("External LDO has been configured"); 433 enable_extldo = TRUE; 434 } 435 436 ALOGE("Write %c to rfkill\n", on); 437 438 /* Write value to control rfkill */ 439 if ((size = write(fd, &on, 1)) < 0) { 440 ALOGE("write(%s) failed: %s (%d)",rfkill_state, strerror(errno),errno); 441 #ifdef WIFI_BT_STATUS_SYNC 442 bt_semaphore_release(lock_fd); 443 bt_semaphore_destroy(lock_fd); 444 #endif 445 return -1; 446 } 447 #ifdef BT_SOC_TYPE_ROME 448 if(on == '0'){ 449 ALOGE("Stopping HCI filter as part of CTRL:OFF"); 450 stop_hci_filter(); 451 property_set("wc_transport.soc_initialized", "0"); 452 } 453 #endif 454 #ifdef WIFI_BT_STATUS_SYNC 455 /* query wifi status */ 456 property_get(WIFI_PROP_NAME, wifi_status, ""); 457 458 ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit); 459 460 /* If wlan driver is not loaded, and bt is changed from off => on */ 461 if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) { 462 if (on == '1') { 463 ALOGI("%s: BT_VND_PWR_ON\n", __func__); 464 if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) { 465 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 466 close(fd); 467 bt_semaphore_release(lock_fd); 468 bt_semaphore_destroy(lock_fd); 469 return -1; 470 } 471 } 472 else if (isInit == 0 && on == '0') { 473 ALOGI("%s: BT_VND_PWR_OFF\n", __func__); 474 if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) { 475 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 476 close(fd); 477 bt_semaphore_release(lock_fd); 478 bt_semaphore_destroy(lock_fd); 479 return -1; 480 } 481 } 482 } 483 484 if (isInit == 0 && on == '0') 485 property_set(BT_STATUS_NAME, "false"); 486 else if (on == '1') 487 property_set(BT_STATUS_NAME, "true"); 488 489 bt_semaphore_release(lock_fd); 490 bt_semaphore_destroy(lock_fd); 491 #endif /* WIFI_BT_STATUS_SYNC */ 492 493 done: 494 if (fd >= 0) 495 close(fd); 496 497 return 0; 498 } 499 500 /***************************************************************************** 501 ** 502 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 503 ** 504 *****************************************************************************/ 505 506 static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr) 507 { 508 int i; 509 510 ALOGI("bt-vendor : init"); 511 512 if (p_cb == NULL) 513 { 514 ALOGE("init failed with no user callbacks!"); 515 return -1; 516 } 517 518 if ((btSocType = get_bt_soc_type()) < 0) { 519 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 520 return -1; 521 } 522 523 switch(btSocType) 524 { 525 case BT_SOC_ROME: 526 case BT_SOC_AR3K: 527 ALOGI("bt-vendor : Initializing UART transport layer"); 528 userial_vendor_init(); 529 break; 530 case BT_SOC_DEFAULT: 531 break; 532 default: 533 ALOGE("Unknown btSocType: 0x%x", btSocType); 534 break; 535 } 536 537 /* store reference to user callbacks */ 538 bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb; 539 540 /* Copy BD Address as little-endian byte order */ 541 if(local_bdaddr) 542 for(i=0;i<6;i++) 543 vnd_local_bd_addr[i] = *(local_bdaddr + (5-i)); 544 545 ALOGI("%s: Local BD Address : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", __FUNCTION__, 546 vnd_local_bd_addr[0], 547 vnd_local_bd_addr[1], 548 vnd_local_bd_addr[2], 549 vnd_local_bd_addr[3], 550 vnd_local_bd_addr[4], 551 vnd_local_bd_addr[5]); 552 553 #ifdef WIFI_BT_STATUS_SYNC 554 isInit = 1; 555 #endif /* WIFI_BT_STATUS_SYNC */ 556 557 return 0; 558 } 559 560 #ifdef READ_BT_ADDR_FROM_PROP 561 static bool validate_tok(char* bdaddr_tok) { 562 int i = 0; 563 bool ret; 564 565 if (strlen(bdaddr_tok) != 2) { 566 ret = FALSE; 567 ALOGE("Invalid token length"); 568 } else { 569 ret = TRUE; 570 for (i=0; i<2; i++) { 571 if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') || 572 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') || 573 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) { 574 ret = TRUE; 575 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i); 576 } else { 577 ret = FALSE; 578 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i); 579 break; 580 } 581 } 582 } 583 return ret; 584 } 585 #endif /*READ_BT_ADDR_FROM_PROP*/ 586 587 int connect_to_local_socket(char* name) { 588 socklen_t len; int sk = -1; 589 590 ALOGE("%s: ACCEPT ", __func__); 591 sk = socket(AF_LOCAL, SOCK_STREAM, 0); 592 if (sk < 0) { 593 ALOGE("Socket creation failure"); 594 return -1; 595 } 596 597 if(socket_local_client_connect(sk, name, 598 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) 599 { 600 ALOGE("failed to connect (%s)", strerror(errno)); 601 close(sk); 602 sk = -1; 603 } else { 604 ALOGE("%s: Connection succeeded\n", __func__); 605 } 606 return sk; 607 } 608 609 bool is_soc_initialized() { 610 bool init = false; 611 char init_value[PROPERTY_VALUE_MAX]; 612 int ret; 613 614 ALOGI("bt-vendor : is_soc_initialized"); 615 616 ret = property_get("wc_transport.soc_initialized", init_value, NULL); 617 if (ret != 0) { 618 ALOGI("wc_transport.soc_initialized set to %s\n", init_value); 619 if (!strncasecmp(init_value, "1", sizeof("1"))) { 620 init = true; 621 } 622 } 623 else { 624 ALOGE("%s: Failed to get wc_transport.soc_initialized", __FUNCTION__); 625 } 626 627 return init; 628 } 629 630 631 /** Requested operations */ 632 static int op(bt_vendor_opcode_t opcode, void *param) 633 { 634 int retval = 0; 635 int nCnt = 0; 636 int nState = -1; 637 bool is_ant_req = false; 638 char wipower_status[PROPERTY_VALUE_MAX]; 639 char emb_wp_mode[PROPERTY_VALUE_MAX]; 640 char bt_version[PROPERTY_VALUE_MAX]; 641 bool ignore_boot_prop = TRUE; 642 #ifdef READ_BT_ADDR_FROM_PROP 643 int i = 0; 644 static char bd_addr[PROPERTY_VALUE_MAX]; 645 uint8_t local_bd_addr_from_prop[6]; 646 char* tok; 647 #endif 648 bool skip_init = true; 649 ALOGV("bt-vendor : op for %d", opcode); 650 651 switch(opcode) 652 { 653 case BT_VND_OP_POWER_CTRL: 654 { 655 nState = *(int *) param; 656 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s", 657 (nState == BT_VND_PWR_ON)? "On" : "Off" ); 658 659 switch(btSocType) 660 { 661 case BT_SOC_DEFAULT: 662 if (readTrpState()) 663 { 664 ALOGI("bt-vendor : resetting BT status"); 665 hw_config(BT_VND_PWR_OFF); 666 } 667 retval = hw_config(nState); 668 if(nState == BT_VND_PWR_ON 669 && retval == 0 670 && is_hw_ready() == TRUE){ 671 retval = 0; 672 } 673 else { 674 retval = -1; 675 } 676 break; 677 case BT_SOC_ROME: 678 case BT_SOC_AR3K: 679 /* BT Chipset Power Control through Device Tree Node */ 680 retval = bt_powerup(nState); 681 default: 682 break; 683 } 684 } 685 break; 686 687 case BT_VND_OP_FW_CFG: 688 { 689 // call hciattach to initalize the stack 690 if(bt_vendor_cbacks){ 691 if (btSocType == BT_SOC_ROME) { 692 if (is_soc_initialized()) { 693 ALOGI("Bluetooth FW and transport layer are initialized"); 694 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 695 } else { 696 ALOGE("bt_vendor_cbacks is null or SoC not initialized"); 697 ALOGE("Error : hci, smd initialization Error"); 698 retval = -1; 699 } 700 } else { 701 ALOGI("Bluetooth FW and transport layer are initialized"); 702 bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 703 } 704 } 705 else{ 706 ALOGE("bt_vendor_cbacks is null"); 707 ALOGE("Error : hci, smd initialization Error"); 708 retval = -1; 709 } 710 } 711 break; 712 713 case BT_VND_OP_SCO_CFG: 714 { 715 if (bt_vendor_cbacks) 716 bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 717 } 718 break; 719 #ifdef BT_SOC_TYPE_ROME 720 #ifdef ENABLE_ANT 721 case BT_VND_OP_ANT_USERIAL_OPEN: 722 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN"); 723 is_ant_req = true; 724 //fall through 725 #endif 726 727 #endif 728 case BT_VND_OP_USERIAL_OPEN: 729 { 730 int (*fd_array)[] = (int (*)[]) param; 731 int idx, fd; 732 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN"); 733 switch(btSocType) 734 { 735 case BT_SOC_DEFAULT: 736 { 737 if(bt_hci_init_transport(pFd) != -1){ 738 int (*fd_array)[] = (int (*) []) param; 739 740 (*fd_array)[CH_CMD] = pFd[0]; 741 (*fd_array)[CH_EVT] = pFd[0]; 742 (*fd_array)[CH_ACL_OUT] = pFd[1]; 743 (*fd_array)[CH_ACL_IN] = pFd[1]; 744 } 745 else { 746 retval = -1; 747 break; 748 } 749 retval = 2; 750 } 751 break; 752 case BT_SOC_AR3K: 753 { 754 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 755 if (fd != -1) { 756 for (idx=0; idx < CH_MAX; idx++) 757 (*fd_array)[idx] = fd; 758 retval = 1; 759 } 760 else { 761 retval = -1; 762 break; 763 } 764 765 /* Vendor Specific Process should happened during userial_open process 766 After userial_open, rx read thread is running immediately, 767 so it will affect VS event read process. 768 */ 769 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0) 770 retval = -1; 771 } 772 break; 773 case BT_SOC_ROME: 774 { 775 wait_for_patch_download(is_ant_req); 776 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 777 if (!is_soc_initialized()) { 778 char* dlnd_inprog = is_ant_req ? "ant" : "bt"; 779 if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) { 780 ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog); 781 } 782 783 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 784 if (fd < 0) { 785 ALOGE("userial_vendor_open returns err"); 786 retval = -1; 787 } else { 788 /* Clock on */ 789 userial_clock_operation(fd, USERIAL_OP_CLK_ON); 790 ALOGD("userial clock on"); 791 if(strcmp(emb_wp_mode, "true") == 0) { 792 property_get("ro.bluetooth.wipower", wipower_status, false); 793 if(strcmp(wipower_status, "true") == 0) { 794 check_embedded_mode(fd); 795 } else { 796 ALOGI("Wipower not enabled"); 797 } 798 } 799 ALOGV("rome_soc_init is started"); 800 property_set("wc_transport.soc_initialized", "0"); 801 #ifdef READ_BT_ADDR_FROM_PROP 802 /*Give priority to read BD address from boot property*/ 803 ignore_boot_prop = FALSE; 804 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) { 805 ALOGV("BD address read from Boot property: %s\n", bd_addr); 806 tok = strtok(bd_addr, ":"); 807 while (tok != NULL) { 808 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16)); 809 if (i>=6) { 810 ALOGE("bd property of invalid length"); 811 ignore_boot_prop = TRUE; 812 break; 813 } 814 if (!validate_tok(tok)) { 815 ALOGE("Invalid token in BD address"); 816 ignore_boot_prop = TRUE; 817 break; 818 } 819 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16); 820 tok = strtok(NULL, ":"); 821 i++; 822 } 823 if (i == 6 && !ignore_boot_prop) { 824 ALOGV("Valid BD address read from prop"); 825 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 826 ignore_boot_prop = FALSE; 827 } else { 828 ALOGE("There are not enough tokens in BD addr"); 829 ignore_boot_prop = TRUE; 830 } 831 } else { 832 ALOGE("BD address boot property not set"); 833 ignore_boot_prop = TRUE; 834 } 835 #endif //READ_BT_ADDR_FROM_PROP 836 /* Always read BD address from NV file */ 837 if(ignore_boot_prop && !bt_vendor_nv_read(1, vnd_local_bd_addr)) 838 { 839 /* Since the BD address is configured in boot time We should not be here */ 840 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm"); 841 } 842 if(rome_soc_init(fd,vnd_local_bd_addr)<0) { 843 retval = -1; 844 userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 845 } else { 846 ALOGV("rome_soc_init is completed"); 847 property_set("wc_transport.soc_initialized", "1"); 848 userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 849 skip_init = false; 850 /*Close the UART port*/ 851 close(fd); 852 } 853 } 854 } 855 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 856 ALOGE("%s: Failed to set property", __FUNCTION__); 857 } 858 859 property_set("wc_transport.clean_up","0"); 860 if (retval != -1) { 861 #ifdef BT_SOC_TYPE_ROME 862 start_hci_filter(); 863 if (is_ant_req) { 864 ALOGV("connect to ant channel"); 865 ant_fd = fd = connect_to_local_socket("ant_sock"); 866 } 867 else 868 #endif 869 { 870 ALOGV("connect to bt channel"); 871 vnd_userial.fd = fd = connect_to_local_socket("bt_sock"); 872 } 873 874 if (fd != -1) { 875 ALOGV("%s: received the socket fd: %d is_ant_req: %d\n", 876 __func__, fd, is_ant_req); 877 if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req) { 878 if (rome_ver >= ROME_VER_3_0) { 879 /* get rome supported feature request */ 880 ALOGE("%s: %x08 %0x", __FUNCTION__,rome_ver, ROME_VER_3_0); 881 rome_get_addon_feature_list(fd); 882 } 883 } 884 if (!skip_init) { 885 /*Skip if already sent*/ 886 enable_controller_log(fd, is_ant_req); 887 skip_init = true; 888 } 889 for (idx=0; idx < CH_MAX; idx++) 890 (*fd_array)[idx] = fd; 891 retval = 1; 892 } 893 else { 894 retval = -1; 895 } 896 } else { 897 if (fd >= 0) 898 close(fd); 899 } 900 } 901 break; 902 default: 903 ALOGE("Unknown btSocType: 0x%x", btSocType); 904 break; 905 } 906 } 907 break; 908 #ifdef BT_SOC_TYPE_ROME 909 #ifdef ENABLE_ANT 910 case BT_VND_OP_ANT_USERIAL_CLOSE: 911 { 912 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE"); 913 property_set("wc_transport.clean_up","1"); 914 if (ant_fd != -1) { 915 ALOGE("closing ant_fd"); 916 close(ant_fd); 917 ant_fd = -1; 918 } 919 } 920 break; 921 #endif 922 #endif 923 case BT_VND_OP_USERIAL_CLOSE: 924 { 925 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE btSocType: %d", btSocType); 926 switch(btSocType) 927 { 928 case BT_SOC_DEFAULT: 929 bt_hci_deinit_transport(pFd); 930 break; 931 932 case BT_SOC_ROME: 933 case BT_SOC_AR3K: 934 property_set("wc_transport.clean_up","1"); 935 userial_vendor_close(); 936 break; 937 default: 938 ALOGE("Unknown btSocType: 0x%x", btSocType); 939 break; 940 } 941 } 942 break; 943 944 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 945 if (btSocType == BT_SOC_AR3K) { 946 uint32_t *timeout_ms = (uint32_t *) param; 947 *timeout_ms = 1000; 948 } 949 break; 950 951 case BT_VND_OP_LPM_SET_MODE: 952 if(btSocType == BT_SOC_AR3K) { 953 uint8_t *mode = (uint8_t *) param; 954 955 if (*mode) { 956 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0); 957 } 958 else { 959 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 960 } 961 if (bt_vendor_cbacks ) 962 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_SUCCESS); 963 } 964 else { 965 // respond with failure as it's already handled by other mechanism 966 if (bt_vendor_cbacks) 967 bt_vendor_cbacks->lpm_cb(BT_VND_OP_RESULT_FAIL); 968 } 969 break; 970 971 case BT_VND_OP_LPM_WAKE_SET_STATE: 972 { 973 switch(btSocType) 974 { 975 case BT_SOC_ROME: 976 { 977 uint8_t *state = (uint8_t *) param; 978 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 979 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT; 980 981 if (wake_assert == 0) 982 ALOGV("ASSERT: Waking up BT-Device"); 983 else if (wake_assert == 1) 984 ALOGV("DEASSERT: Allowing BT-Device to Sleep"); 985 986 #ifdef QCOM_BT_SIBS_ENABLE 987 if(bt_vendor_cbacks){ 988 ALOGI("Invoking HCI H4 callback function"); 989 bt_vendor_cbacks->lpm_set_state_cb(wake_assert); 990 } 991 #endif 992 } 993 break; 994 case BT_SOC_AR3K: 995 { 996 uint8_t *state = (uint8_t *) param; 997 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 998 UPIO_ASSERT : UPIO_DEASSERT; 999 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0); 1000 } 1001 case BT_SOC_DEFAULT: 1002 break; 1003 default: 1004 ALOGE("Unknown btSocType: 0x%x", btSocType); 1005 break; 1006 } 1007 } 1008 break; 1009 case BT_VND_OP_EPILOG: 1010 { 1011 #if (HW_NEED_END_WITH_HCI_RESET == FALSE) 1012 if (bt_vendor_cbacks) 1013 { 1014 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1015 } 1016 #else 1017 switch(btSocType) 1018 { 1019 case BT_SOC_ROME: 1020 { 1021 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1022 property_get("wc_transport.hci_filter_status", value, "0"); 1023 if(is_soc_initialized()&& (strcmp(value,"1") == 0)) 1024 { 1025 hw_epilog_process(); 1026 } 1027 else 1028 { 1029 if (bt_vendor_cbacks) 1030 { 1031 ALOGE("vendor lib epilog process aborted"); 1032 bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1033 } 1034 } 1035 } 1036 break; 1037 default: 1038 hw_epilog_process(); 1039 break; 1040 } 1041 #endif 1042 } 1043 break; 1044 case BT_VND_OP_GET_LINESPEED: 1045 { 1046 retval = -1; 1047 switch(btSocType) 1048 { 1049 case BT_SOC_ROME: 1050 if(!is_soc_initialized()) { 1051 ALOGE("BT_VND_OP_GET_LINESPEED: error" 1052 " - transport driver not initialized!"); 1053 }else { 1054 retval = 3000000; 1055 } 1056 break; 1057 default: 1058 retval = userial_vendor_get_baud(); 1059 break; 1060 } 1061 break; 1062 } 1063 } 1064 1065 return retval; 1066 } 1067 1068 static void ssr_cleanup(int reason) { 1069 int pwr_state=BT_VND_PWR_OFF; 1070 int ret; 1071 unsigned char trig_ssr = 0xEE; 1072 ALOGI("ssr_cleanup"); 1073 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 1074 ALOGE("%s: Failed to set property", __FUNCTION__); 1075 } 1076 1077 if ((btSocType = get_bt_soc_type()) < 0) { 1078 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 1079 return -1; 1080 } 1081 1082 if (btSocType == BT_SOC_ROME) { 1083 #ifdef BT_SOC_TYPE_ROME 1084 #ifdef ENABLE_ANT 1085 //Indicate to filter by sending 1086 //special byte 1087 if (reason == CMD_TIMEOUT) { 1088 trig_ssr = 0xEE; 1089 ret = write (vnd_userial.fd, &trig_ssr, 1); 1090 ALOGI("Trig_ssr is being sent to BT socket, retval(%d) :errno: %s", ret, strerror(errno)); 1091 1092 if (is_debug_force_special_bytes()) { 1093 //Then we should send special byte to crash SOC in WCNSS_Filter, so we do not 1094 //need to power off UART here. 1095 return; 1096 } 1097 } 1098 1099 /*Close both ANT channel*/ 1100 op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL); 1101 #endif 1102 #endif 1103 /*Close both BT channel*/ 1104 op(BT_VND_OP_USERIAL_CLOSE, NULL); 1105 /*CTRL OFF twice to make sure hw 1106 * turns off*/ 1107 #ifdef ENABLE_ANT 1108 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1109 #endif 1110 1111 } 1112 #ifdef BT_SOC_TYPE_ROME 1113 /*Generally switching of chip should be enough*/ 1114 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1115 #endif 1116 } 1117 1118 1119 /** Closes the interface */ 1120 static void cleanup( void ) 1121 { 1122 ALOGI("cleanup"); 1123 bt_vendor_cbacks = NULL; 1124 1125 #ifdef WIFI_BT_STATUS_SYNC 1126 isInit = 0; 1127 #endif /* WIFI_BT_STATUS_SYNC */ 1128 } 1129 1130 /* Check for one of the cients ANT/BT patch download is already in 1131 ** progress if yes wait till complete 1132 */ 1133 void wait_for_patch_download(bool is_ant_req) { 1134 ALOGV("%s:", __FUNCTION__); 1135 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 1136 while (1) { 1137 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 1138 1139 if(is_ant_req && !strcmp(inProgress,"bt") ) { 1140 //ANT request, wait for BT to finish 1141 usleep(50000); 1142 } 1143 else if(!is_ant_req && !strcmp(inProgress,"ant") ) { 1144 //BT request, wait for ANT to finish 1145 usleep(50000); 1146 } 1147 else { 1148 ALOGI("%s: patch download completed", __FUNCTION__); 1149 break; 1150 } 1151 } 1152 } 1153 1154 static bool is_debug_force_special_bytes() { 1155 int ret = 0; 1156 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1157 bool enabled = false; 1158 1159 ret = property_get("wc_transport.force_special_byte", value, NULL); 1160 1161 if (ret) { 1162 enabled = (strcmp(value, "false") ==0) ? false : true; 1163 ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ", 1164 __func__, value, enabled); 1165 } 1166 1167 return enabled; 1168 } 1169 1170 // Entry point of DLib 1171 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 1172 sizeof(bt_vendor_interface_t), 1173 init, 1174 op, 1175 cleanup, 1176 ssr_cleanup 1177 }; 1178