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 #define LOG_TAG "bt_vendor" 27 #define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr" 28 29 #include <utils/Log.h> 30 #include <cutils/properties.h> 31 #include <fcntl.h> 32 #include <termios.h> 33 #include "bt_vendor_qcom.h" 34 #include "hci_uart.h" 35 #include "hci_smd.h" 36 #include <sys/ioctl.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 30 45 46 #define STOP_WCNSS_FILTER 0xDD 47 #define STOP_WAIT_TIMEOUT 1000 48 49 #define SOC_INIT_PROPERTY "wc_transport.soc_initialized" 50 51 #define BT_VND_FILTER_START "wc_transport.start_hci" 52 53 #define CMD_TIMEOUT 0x22 54 55 static void wait_for_patch_download(bool is_ant_req); 56 static bool is_debug_force_special_bytes(void); 57 int connect_to_local_socket(char* name); 58 /****************************************************************************** 59 ** Externs 60 ******************************************************************************/ 61 extern int hw_config(int nState); 62 extern int is_hw_ready(); 63 extern int chipset_ver; 64 65 /****************************************************************************** 66 ** Variables 67 ******************************************************************************/ 68 struct bt_qcom_struct *q = NULL; 69 pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER; 70 71 int userial_clock_operation(int fd, int cmd); 72 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti); 73 int userial_vendor_get_baud(void); 74 int readTrpState(); 75 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity); 76 bool is_download_progress(); 77 78 static const tUSERIAL_CFG userial_init_cfg = 79 { 80 (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), 81 USERIAL_BAUD_115200 82 }; 83 84 #if (HW_NEED_END_WITH_HCI_RESET == TRUE) 85 void __hw_epilog_process(void); 86 #endif 87 88 #ifdef WIFI_BT_STATUS_SYNC 89 #include <string.h> 90 #include <errno.h> 91 #include <dlfcn.h> 92 #include "cutils/properties.h" 93 94 static const char WIFI_PROP_NAME[] = "wlan.driver.status"; 95 static const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl"; 96 static const char BT_STATUS_NAME[] = "bluetooth.enabled"; 97 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl"; 98 99 #define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock" 100 int isInit=0; 101 #endif /* WIFI_BT_STATUS_SYNC */ 102 bool is_soc_initialized(void); 103 104 /****************************************************************************** 105 ** Local type definitions 106 ******************************************************************************/ 107 108 /****************************************************************************** 109 ** Functions 110 ******************************************************************************/ 111 #ifdef WIFI_BT_STATUS_SYNC 112 int bt_semaphore_create(void) 113 { 114 int fd; 115 116 fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY); 117 118 if (fd < 0) 119 ALOGE("can't create file\n"); 120 121 return fd; 122 } 123 124 int bt_semaphore_get(int fd) 125 { 126 int ret; 127 128 if (fd < 0) 129 return -1; 130 131 ret = flock(fd, LOCK_EX); 132 if (ret != 0) { 133 ALOGE("can't hold lock: %s\n", strerror(errno)); 134 return -1; 135 } 136 137 return ret; 138 } 139 140 int bt_semaphore_release(int fd) 141 { 142 int ret; 143 144 if (fd < 0) 145 return -1; 146 147 ret = flock(fd, LOCK_UN); 148 if (ret != 0) { 149 ALOGE("can't release lock: %s\n", strerror(errno)); 150 return -1; 151 } 152 153 return ret; 154 } 155 156 int bt_semaphore_destroy(int fd) 157 { 158 if (fd < 0) 159 return -1; 160 161 return close (fd); 162 } 163 164 int bt_wait_for_service_done(void) 165 { 166 char service_status[PROPERTY_VALUE_MAX]; 167 int count = 30; 168 169 ALOGE("%s: check\n", __func__); 170 171 /* wait for service done */ 172 while (count-- > 0) { 173 property_get(WIFI_SERVICE_PROP, service_status, NULL); 174 175 if (strcmp(service_status, "") != 0) { 176 usleep(200000); 177 } else { 178 break; 179 } 180 } 181 182 return 0; 183 } 184 185 #endif /* WIFI_BT_STATUS_SYNC */ 186 187 /** Get Bluetooth SoC type from system setting */ 188 static int get_bt_soc_type() 189 { 190 int ret = 0; 191 char bt_soc_type[PROPERTY_VALUE_MAX]; 192 193 ALOGI("bt-vendor : get_bt_soc_type"); 194 195 ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL); 196 if (ret != 0) { 197 ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type); 198 if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) { 199 return BT_SOC_ROME; 200 } 201 else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) { 202 return BT_SOC_CHEROKEE; 203 } 204 else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) { 205 return BT_SOC_AR3K; 206 } 207 else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) { 208 return BT_SOC_CHEROKEE; 209 } 210 else { 211 ALOGI("qcom.bluetooth.soc not set, so using default.\n"); 212 return BT_SOC_DEFAULT; 213 } 214 } 215 else { 216 ALOGE("%s: Failed to get soc type", __FUNCTION__); 217 ret = BT_SOC_DEFAULT; 218 } 219 220 return ret; 221 } 222 223 bool can_perform_action(char action) { 224 bool can_perform = false; 225 char ref_count[PROPERTY_VALUE_MAX]; 226 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 227 int value, ret; 228 229 property_get("wc_transport.ref_count", ref_count, "0"); 230 231 value = atoi(ref_count); 232 ALOGV("%s: ref_count: %s\n",__func__, ref_count); 233 234 if(action == '1') { 235 ALOGV("%s: on : value is: %d", __func__, value); 236 if(value == 1) 237 { 238 if ((is_soc_initialized() == true) 239 || is_download_progress() || get_bt_soc_type() == BT_SOC_CHEROKEE) 240 { 241 value++; 242 ALOGV("%s: on : value is incremented to : %d", __func__, value); 243 } 244 } 245 else 246 { 247 value++; 248 } 249 250 if (value == 1) 251 can_perform = true; 252 else if (value > 3) 253 return false; 254 } 255 else { 256 ALOGV("%s: off : value is: %d", __func__, value); 257 if (--value <= 0) { 258 ALOGE("%s: BT turn off twice before BT On(ref_count=%d)\n", 259 __func__, value); 260 value = 0; 261 can_perform = true; 262 } 263 } 264 265 snprintf(ref_count, 3, "%d", value); 266 ALOGV("%s: updated ref_count is: %s", __func__, ref_count); 267 268 ret = property_set("wc_transport.ref_count", ref_count); 269 if (ret < 0) { 270 ALOGE("%s: Error while updating property: %d\n", __func__, ret); 271 return false; 272 } 273 ALOGV("%s returning %d", __func__, can_perform); 274 return can_perform; 275 } 276 277 void stop_hci_filter() { 278 char value[PROPERTY_VALUE_MAX] = {'\0'}; 279 int retval, filter_ctrl, i; 280 char stop_val = STOP_WCNSS_FILTER; 281 int soc_type = BT_SOC_DEFAULT; 282 283 ALOGV("%s: Entry ", __func__); 284 285 if ((soc_type = get_bt_soc_type()) == BT_SOC_CHEROKEE) { 286 property_get("wc_transport.hci_filter_status", value, "0"); 287 if (strcmp(value, "0") == 0) { 288 ALOGI("%s: hci_filter has been stopped already", __func__); 289 } 290 else { 291 filter_ctrl = connect_to_local_socket("wcnssfilter_ctrl"); 292 if (filter_ctrl < 0) { 293 ALOGI("%s: Error while connecting to CTRL_SOCK, filter should stopped: %d", 294 __func__, filter_ctrl); 295 } 296 else { 297 retval = write(filter_ctrl, &stop_val, 1); 298 if (retval != 1) { 299 ALOGI("%s: problem writing to CTRL_SOCK, ignore: %d", __func__, retval); 300 //Ignore and fallback 301 } 302 303 close(filter_ctrl); 304 } 305 } 306 307 /* Ensure Filter is closed by checking the status before 308 RFKILL 0 operation. this should ideally comeout very 309 quick */ 310 for(i=0; i<500; i++) { 311 property_get(BT_VND_FILTER_START, value, "false"); 312 if (strcmp(value, "false") == 0) { 313 ALOGI("%s: WCNSS_FILTER stopped", __func__); 314 usleep(STOP_WAIT_TIMEOUT * 10); 315 break; 316 } else { 317 /*sleep of 1ms, This should give enough time for FILTER to 318 exit with all necessary cleanup*/ 319 usleep(STOP_WAIT_TIMEOUT); 320 } 321 } 322 323 /*Never use SIGKILL to stop the filter*/ 324 /* Filter will be stopped by below two conditions 325 - by Itself, When it realizes there are no CONNECTED clients 326 - Or through STOP_WCNSS_FILTER byte on Control socket 327 both of these ensure clean shutdown of chip 328 */ 329 //property_set(BT_VND_FILTER_START, "false"); 330 } else if (soc_type == BT_SOC_ROME) { 331 property_set(BT_VND_FILTER_START, "false"); 332 } else { 333 ALOGI("%s: Unknown soc type %d, Unexpected!", __func__, soc_type); 334 } 335 336 ALOGV("%s: Exit ", __func__); 337 } 338 339 int start_hci_filter() { 340 ALOGV("%s: Entry ", __func__); 341 int i, init_success = -1; 342 char value[PROPERTY_VALUE_MAX] = {'\0'}; 343 344 property_get(BT_VND_FILTER_START, value, false); 345 346 if (strcmp(value, "true") == 0) { 347 ALOGI("%s: hci_filter has been started already", __func__); 348 //Filter should have been started OR in the process of initializing 349 //Make sure of hci_filter_status and return the state based on it 350 } else { 351 352 property_set("wc_transport.hci_filter_status", "0"); 353 property_set(BT_VND_FILTER_START, "true"); 354 ALOGV("%s: %s set to true ", __func__, BT_VND_FILTER_START ); 355 } 356 357 /*If there are back to back ON requests from different clients, 358 All client should come and stuck in this while loop till FILTER 359 comesup and ready to accept the connections */ 360 //sched_yield(); 361 for(i=0; i<45; i++) { 362 property_get("wc_transport.hci_filter_status", value, "0"); 363 if (strcmp(value, "1") == 0) { 364 init_success = 1; 365 break; 366 } else { 367 usleep(WAIT_TIMEOUT); 368 } 369 } 370 ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i); 371 372 ALOGV("%s: Exit ", __func__); 373 return init_success; 374 } 375 376 /* 377 * Bluetooth Controller power up or shutdown, this function is called with 378 * q_lock held and q is non-NULL 379 */ 380 static int bt_powerup(int en ) 381 { 382 char rfkill_type[64], *enable_ldo_path = NULL; 383 char type[16], enable_ldo[6]; 384 int fd = 0, size, i, ret, fd_ldo, fd_btpower; 385 386 char disable[PROPERTY_VALUE_MAX]; 387 char state; 388 char on = (en)?'1':'0'; 389 390 #ifdef WIFI_BT_STATUS_SYNC 391 char wifi_status[PROPERTY_VALUE_MAX]; 392 int lock_fd; 393 #endif /*WIFI_BT_STATUS_SYNC*/ 394 395 ALOGI("bt_powerup: %c", on); 396 397 /* Check if rfkill has been disabled */ 398 ret = property_get("ro.rfkilldisabled", disable, "0"); 399 if (!ret ){ 400 ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret); 401 return -1; 402 } 403 /* In case rfkill disabled, then no control power*/ 404 if (strcmp(disable, "1") == 0) { 405 ALOGI("ro.rfkilldisabled : %s", disable); 406 return -1; 407 } 408 409 #ifdef WIFI_BT_STATUS_SYNC 410 lock_fd = bt_semaphore_create(); 411 bt_semaphore_get(lock_fd); 412 bt_wait_for_service_done(); 413 #endif 414 415 /* Assign rfkill_id and find bluetooth rfkill state path*/ 416 for(i = 0; (q->rfkill_id == -1) && (q->rfkill_state == NULL); i++) 417 { 418 snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i); 419 if ((fd = open(rfkill_type, O_RDONLY)) < 0) 420 { 421 ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno); 422 423 #ifdef WIFI_BT_STATUS_SYNC 424 bt_semaphore_release(lock_fd); 425 bt_semaphore_destroy(lock_fd); 426 #endif 427 return -1; 428 } 429 430 size = read(fd, &type, sizeof(type)); 431 close(fd); 432 433 if ((size >= 9) && !memcmp(type, "bluetooth", 9)) 434 { 435 asprintf(&q->rfkill_state, "/sys/class/rfkill/rfkill%d/state", q->rfkill_id = i); 436 break; 437 } 438 } 439 440 /* Get rfkill State to control */ 441 if (q->rfkill_state != NULL) 442 { 443 if ((fd = open(q->rfkill_state, O_RDWR)) < 0) 444 { 445 ALOGE("open(%s) for write failed: %s (%d)", q->rfkill_state, strerror(errno), errno); 446 #ifdef WIFI_BT_STATUS_SYNC 447 bt_semaphore_release(lock_fd); 448 bt_semaphore_destroy(lock_fd); 449 #endif 450 451 return -1; 452 } 453 } 454 /* Always perform BT power action so as to have the chance to 455 recover BT power properly from un-expected error. */ 456 #ifdef CHECK_BT_POWER_PERFORM_ACTION 457 if(can_perform_action(on) == false) { 458 ALOGE("%s:can't perform action as it is being used by other clients", __func__); 459 #ifdef WIFI_BT_STATUS_SYNC 460 bt_semaphore_release(lock_fd); 461 bt_semaphore_destroy(lock_fd); 462 #endif 463 goto done; 464 } 465 #else 466 ALOGI("%s: always perform action", __func__); 467 #endif 468 ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id); 469 if( (ret < 0 ) || (enable_ldo_path == NULL) ) 470 { 471 ALOGE("Memory Allocation failure"); 472 return -1; 473 } 474 if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) { 475 ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 476 return -1; 477 } 478 size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo)); 479 close(fd_ldo); 480 if (size <= 0) { 481 ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 482 return -1; 483 } 484 if (!memcmp(enable_ldo, "true", 4)) { 485 ALOGI("External LDO has been configured"); 486 ret = property_set("wc_transport.extldo", "enabled"); 487 if (ret < 0) { 488 ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__); 489 } 490 q->enable_extldo = TRUE; 491 } 492 493 if(on == '0'){ 494 ALOGE("Stopping HCI filter as part of CTRL:OFF"); 495 stop_hci_filter(); 496 property_set("wc_transport.soc_initialized", "0"); 497 } 498 499 if (q->soc_type >= BT_SOC_CHEROKEE && q->soc_type < BT_SOC_RESERVED) { 500 ALOGI("open bt power devnode,send ioctl power op :%d ",en); 501 fd_btpower = open(BT_PWR_CNTRL_DEVICE, O_RDWR, O_NONBLOCK); 502 if (fd_btpower < 0) { 503 ALOGE("\nfailed to open bt device error = (%s)\n",strerror(errno)); 504 #ifdef WIFI_BT_STATUS_SYNC 505 bt_semaphore_release(lock_fd); 506 bt_semaphore_destroy(lock_fd); 507 #endif 508 return -1; 509 } 510 ret = ioctl(fd_btpower, BT_CMD_PWR_CTRL, (unsigned long)en); 511 if (ret < 0) { 512 ALOGE(" ioctl failed to power control:%d error =(%s)",ret,strerror(errno)); 513 } 514 close(fd_btpower); 515 } else { 516 ALOGI("Write %c to rfkill\n", on); 517 /* Write value to control rfkill */ 518 if(fd >= 0) { 519 if ((size = write(fd, &on, 1)) < 0) { 520 ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno); 521 #ifdef WIFI_BT_STATUS_SYNC 522 bt_semaphore_release(lock_fd); 523 bt_semaphore_destroy(lock_fd); 524 #endif 525 return -1; 526 } 527 } 528 } 529 #ifdef WIFI_BT_STATUS_SYNC 530 /* query wifi status */ 531 property_get(WIFI_PROP_NAME, wifi_status, ""); 532 533 ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit); 534 535 /* If wlan driver is not loaded, and bt is changed from off => on */ 536 if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) { 537 if (on == '1') { 538 ALOGI("%s: BT_VND_PWR_ON\n", __func__); 539 if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) { 540 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 541 close(fd); 542 bt_semaphore_release(lock_fd); 543 bt_semaphore_destroy(lock_fd); 544 return -1; 545 } 546 } 547 else if (isInit == 0 && on == '0') { 548 ALOGI("%s: BT_VND_PWR_OFF\n", __func__); 549 if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) { 550 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 551 close(fd); 552 bt_semaphore_release(lock_fd); 553 bt_semaphore_destroy(lock_fd); 554 return -1; 555 } 556 } 557 } 558 559 if (isInit == 0 && on == '0') 560 property_set(BT_STATUS_NAME, "false"); 561 else if (on == '1') 562 property_set(BT_STATUS_NAME, "true"); 563 564 bt_semaphore_release(lock_fd); 565 bt_semaphore_destroy(lock_fd); 566 #endif /* WIFI_BT_STATUS_SYNC */ 567 568 done: 569 if (fd >= 0) 570 close(fd); 571 return 0; 572 } 573 574 static inline void soc_init(int soc_type) 575 { 576 switch (soc_type) 577 { 578 case BT_SOC_CHEROKEE: 579 case BT_SOC_ROME: 580 case BT_SOC_AR3K: 581 ALOGI("bt-vendor : Initializing UART transport layer"); 582 userial_vendor_init(); 583 break; 584 case BT_SOC_DEFAULT: 585 break; 586 default: 587 ALOGE("Unknown soc yype: %d", soc_type); 588 break; 589 } 590 } 591 592 /* Copy BD Address as little-endian byte order */ 593 static inline void le2bd(unsigned char *src, unsigned char *dst) 594 { 595 int i; 596 for (i = 0; i < 6; i++) 597 dst[i] = src[5-i]; 598 } 599 600 static inline void print_bdaddr(unsigned char *addr) 601 { 602 ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1], 603 addr[2], addr[3], addr[4], addr[5]); 604 } 605 606 /***************************************************************************** 607 ** 608 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 609 ** 610 *****************************************************************************/ 611 612 static int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr) 613 { 614 char prop[PROPERTY_VALUE_MAX] = {0}; 615 struct bt_qcom_struct *temp = NULL; 616 int ret = BT_STATUS_SUCCESS, i; 617 618 ALOGI("++%s", __FUNCTION__); 619 620 if (!cb || !bdaddr) { 621 ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr); 622 ret = -BT_STATUS_INVAL; 623 goto out; 624 } 625 626 temp = (struct bt_qcom_struct *) malloc(sizeof(*q)); 627 if (!temp) { 628 ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno); 629 ret = -BT_STATUS_NOMEM; 630 goto out; 631 } 632 memset(temp, 0, sizeof(*temp)); 633 634 temp->rfkill_id = -1; 635 temp->enable_extldo = FALSE; 636 temp->cb = cb; 637 temp->ant_fd = -1; 638 temp->soc_type = get_bt_soc_type(); 639 soc_init(temp->soc_type); 640 641 le2bd(bdaddr, temp->bdaddr); 642 print_bdaddr(temp->bdaddr); 643 snprintf(prop, sizeof(prop), "%02x:%02x:%02x:%02x:%02x:%02x", 644 temp->bdaddr[0], temp->bdaddr[1], temp->bdaddr[2], 645 temp->bdaddr[3], temp->bdaddr[4], temp->bdaddr[5]); 646 ret = property_set("wc_transport.stack_bdaddr", prop); 647 if (ret < 0) { 648 ALOGE("Failed to set wc_transport.stack_bdaddr prop, ret = %d", ret); 649 ret = -BT_STATUS_PROP_FAILURE; 650 goto out; 651 } 652 653 /* TODO: Move these fields inside bt_qcom context */ 654 #ifdef WIFI_BT_STATUS_SYNC 655 isInit = 1; 656 #endif /* WIFI_BT_STATUS_SYNC */ 657 658 /* Everything successful */ 659 q = temp; 660 return ret; 661 662 out: 663 if (temp) 664 free(temp); 665 ALOGI("--%s ret %d", __FUNCTION__, ret); 666 return ret; 667 } 668 669 #ifdef READ_BT_ADDR_FROM_PROP 670 static bool validate_tok(char* bdaddr_tok) { 671 int i = 0; 672 bool ret; 673 674 if (strlen(bdaddr_tok) != 2) { 675 ret = FALSE; 676 ALOGE("Invalid token length"); 677 } else { 678 ret = TRUE; 679 for (i=0; i<2; i++) { 680 if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') || 681 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') || 682 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) { 683 ret = TRUE; 684 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i); 685 } else { 686 ret = FALSE; 687 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i); 688 break; 689 } 690 } 691 } 692 return ret; 693 } 694 #endif /*READ_BT_ADDR_FROM_PROP*/ 695 696 int connect_to_local_socket(char* name) { 697 socklen_t len; int sk = -1; 698 699 ALOGE("%s: ACCEPT ", __func__); 700 sk = socket(AF_LOCAL, SOCK_STREAM, 0); 701 if (sk < 0) { 702 ALOGE("Socket creation failure"); 703 return -1; 704 } 705 706 if(socket_local_client_connect(sk, name, 707 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) 708 { 709 ALOGE("failed to connect (%s)", strerror(errno)); 710 close(sk); 711 sk = -1; 712 } else { 713 ALOGE("%s: Connection succeeded\n", __func__); 714 } 715 return sk; 716 } 717 718 bool is_soc_initialized() { 719 bool init = false; 720 char init_value[PROPERTY_VALUE_MAX]; 721 int ret; 722 723 ALOGI("bt-vendor : is_soc_initialized"); 724 725 ret = property_get(SOC_INIT_PROPERTY, init_value, NULL); 726 if (ret != 0) { 727 ALOGI("%s set to %s\n", SOC_INIT_PROPERTY, init_value); 728 if (!strncasecmp(init_value, "1", sizeof("1"))) { 729 init = true; 730 } 731 } 732 else { 733 ALOGE("%s: Failed to get %s", __FUNCTION__, SOC_INIT_PROPERTY); 734 } 735 736 return init; 737 } 738 739 /* flavor of op without locks */ 740 static int __op(bt_vendor_opcode_t opcode, void *param) 741 { 742 int retval = BT_STATUS_SUCCESS; 743 int nCnt = 0; 744 int nState = -1; 745 bool is_ant_req = false; 746 bool is_fm_req = false; 747 char wipower_status[PROPERTY_VALUE_MAX]; 748 char emb_wp_mode[PROPERTY_VALUE_MAX]; 749 char bt_version[PROPERTY_VALUE_MAX]; 750 char lpm_config[PROPERTY_VALUE_MAX]; 751 bool ignore_boot_prop = TRUE; 752 #ifdef READ_BT_ADDR_FROM_PROP 753 int i = 0; 754 static char bd_addr[PROPERTY_VALUE_MAX]; 755 uint8_t local_bd_addr_from_prop[6]; 756 char* tok; 757 #endif 758 bool skip_init = true; 759 int opcode_init = opcode; 760 ALOGV("++%s opcode %d", __FUNCTION__, opcode); 761 762 switch(opcode_init) 763 { 764 #ifdef FM_OVER_UART 765 case FM_VND_OP_POWER_CTRL: 766 { 767 is_fm_req = true; 768 if (is_soc_initialized()) { 769 // add any FM specific actions if needed in future 770 break; 771 } 772 } 773 #endif 774 case BT_VND_OP_POWER_CTRL: 775 { 776 if (!param) { 777 ALOGE("opcode = %d: param is null", opcode_init); 778 break; 779 } 780 nState = *(int *) param; 781 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s", 782 (nState == BT_VND_PWR_ON)? "On" : "Off" ); 783 784 switch(q->soc_type) 785 { 786 case BT_SOC_DEFAULT: 787 if (readTrpState()) 788 { 789 ALOGI("bt-vendor : resetting BT status"); 790 hw_config(BT_VND_PWR_OFF); 791 } 792 retval = hw_config(nState); 793 if(nState == BT_VND_PWR_ON 794 && retval == 0 795 && is_hw_ready() == TRUE){ 796 retval = 0; 797 } 798 else { 799 retval = -1; 800 } 801 break; 802 case BT_SOC_ROME: 803 case BT_SOC_AR3K: 804 case BT_SOC_CHEROKEE: 805 if (q->soc_type == BT_SOC_ROME) 806 { 807 if (nState == BT_VND_PWR_ON) 808 { 809 /* Always power BT off before power on. */ 810 ALOGI("bt-vendor: always power off before power on"); 811 bt_powerup(BT_VND_PWR_OFF); 812 } 813 } 814 815 /* BT Chipset Power Control through Device Tree Node */ 816 retval = bt_powerup(nState); 817 default: 818 break; 819 } 820 } 821 break; 822 823 case BT_VND_OP_FW_CFG: { 824 /* call hciattach to initalize the stack */ 825 if (q->soc_type == BT_SOC_ROME) { 826 if (is_soc_initialized()) { 827 ALOGI("Bluetooth FW and transport layer are initialized"); 828 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 829 } else { 830 ALOGE("bt_vendor_cbacks is null or SoC not initialized"); 831 ALOGE("Error : hci, smd initialization Error"); 832 retval = -1; 833 } 834 } else { 835 ALOGI("Bluetooth FW and transport layer are initialized"); 836 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 837 } 838 } 839 break; 840 841 case BT_VND_OP_SCO_CFG: 842 q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 843 break; 844 #ifdef ENABLE_ANT 845 case BT_VND_OP_ANT_USERIAL_OPEN: 846 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN"); 847 is_ant_req = true; 848 goto userial_open; 849 #endif 850 #ifdef FM_OVER_UART 851 case BT_VND_OP_FM_USERIAL_OPEN: 852 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_OPEN"); 853 is_fm_req = true; 854 goto userial_open; 855 #endif 856 userial_open: 857 case BT_VND_OP_USERIAL_OPEN: 858 { 859 if (!param) { 860 ALOGE("opcode = %d: param is null", opcode_init); 861 break; 862 } 863 int (*fd_array)[] = (int (*)[]) param; 864 int idx, fd = -1, fd_filter = -1; 865 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN"); 866 switch(q->soc_type) 867 { 868 case BT_SOC_DEFAULT: 869 { 870 if(bt_hci_init_transport(q->fd) != -1){ 871 int (*fd_array)[] = (int (*) []) param; 872 873 (*fd_array)[CH_CMD] = q->fd[0]; 874 (*fd_array)[CH_EVT] = q->fd[0]; 875 (*fd_array)[CH_ACL_OUT] = q->fd[1]; 876 (*fd_array)[CH_ACL_IN] = q->fd[1]; 877 } 878 else { 879 retval = -1; 880 break; 881 } 882 retval = 2; 883 } 884 break; 885 case BT_SOC_AR3K: 886 { 887 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 888 if (fd != -1) { 889 for (idx=0; idx < CH_MAX; idx++) 890 (*fd_array)[idx] = fd; 891 retval = 1; 892 } 893 else { 894 retval = -1; 895 break; 896 } 897 898 /* Vendor Specific Process should happened during userial_open process 899 After userial_open, rx read thread is running immediately, 900 so it will affect VS event read process. 901 */ 902 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0) 903 retval = -1; 904 } 905 break; 906 case BT_SOC_ROME: 907 { 908 wait_for_patch_download(is_ant_req); 909 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 910 if (!is_soc_initialized()) { 911 char* dlnd_inprog = is_ant_req ? "ant" : "bt"; 912 if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) { 913 ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog); 914 } 915 916 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 917 if (fd < 0) { 918 ALOGE("userial_vendor_open returns err"); 919 retval = -1; 920 break; 921 } 922 923 /* Clock on */ 924 userial_clock_operation(fd, USERIAL_OP_CLK_ON); 925 926 if(strcmp(emb_wp_mode, "true") == 0) { 927 property_get("ro.bluetooth.wipower", wipower_status, false); 928 if(strcmp(wipower_status, "true") == 0) { 929 check_embedded_mode(fd); 930 } else { 931 ALOGI("Wipower not enabled"); 932 } 933 } 934 ALOGV("rome_soc_init is started"); 935 property_set("wc_transport.soc_initialized", "0"); 936 #ifdef READ_BT_ADDR_FROM_PROP 937 /*Give priority to read BD address from boot property*/ 938 ignore_boot_prop = FALSE; 939 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) { 940 ALOGV("BD address read from Boot property: %s\n", bd_addr); 941 tok = strtok(bd_addr, ":"); 942 while (tok != NULL) { 943 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16)); 944 if (i>=6) { 945 ALOGE("bd property of invalid length"); 946 ignore_boot_prop = TRUE; 947 break; 948 } 949 if (i == 6 && !ignore_boot_prop) { 950 ALOGV("Valid BD address read from prop"); 951 memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 952 ignore_boot_prop = FALSE; 953 } else { 954 ALOGE("There are not enough tokens in BD addr"); 955 ignore_boot_prop = TRUE; 956 break; 957 } 958 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16); 959 tok = strtok(NULL, ":"); 960 i++; 961 } 962 if (i == 6 && !ignore_boot_prop) { 963 ALOGV("Valid BD address read from prop"); 964 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 965 ignore_boot_prop = FALSE; 966 } else { 967 ALOGE("There are not enough tokens in BD addr"); 968 ignore_boot_prop = TRUE; 969 } 970 } 971 else { 972 ALOGE("BD address boot property not set"); 973 ignore_boot_prop = TRUE; 974 } 975 #endif //READ_BT_ADDR_FROM_PROP 976 /* Always read BD address from NV file */ 977 if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr)) 978 { 979 /* Since the BD address is configured in boot time We should not be here */ 980 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm"); 981 } 982 if(rome_soc_init(fd, (char*)q->bdaddr)<0) { 983 retval = -1; 984 } else { 985 ALOGV("rome_soc_init is completed"); 986 property_set("wc_transport.soc_initialized", "1"); 987 skip_init = false; 988 } 989 } 990 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 991 ALOGE("%s: Failed to set property", __FUNCTION__); 992 } 993 994 property_set("wc_transport.clean_up","0"); 995 if (retval != -1) { 996 997 retval = start_hci_filter(); 998 if (retval < 0) { 999 ALOGE("%s: WCNSS_FILTER wouldn't have started in time\n", __func__); 1000 } else { 1001 #ifdef ENABLE_ANT 1002 if (is_ant_req) { 1003 ALOGI("%s: connect to ant channel", __func__); 1004 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 1005 } 1006 else 1007 #endif 1008 { 1009 ALOGI("%s: connect to bt channel", __func__); 1010 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 1011 } 1012 1013 if (fd_filter != -1) { 1014 ALOGI("%s: received the socket fd: %d is_ant_req: %d is_fm_req: %d\n", 1015 __func__, fd_filter, is_ant_req,is_fm_req); 1016 if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req && !is_fm_req) { 1017 if (chipset_ver >= ROME_VER_3_0) { 1018 /* get rome supported feature request */ 1019 ALOGE("%s: %x08 %0x", __FUNCTION__,chipset_ver, ROME_VER_3_0); 1020 rome_get_addon_feature_list(fd_filter); 1021 } 1022 } 1023 if (!skip_init) { 1024 /*Skip if already sent*/ 1025 enable_controller_log(fd_filter, (is_ant_req || is_fm_req) ); 1026 skip_init = true; 1027 } 1028 for (idx=0; idx < CH_MAX; idx++) 1029 (*fd_array)[idx] = fd_filter; 1030 retval = 1; 1031 } 1032 else { 1033 if (is_ant_req) 1034 ALOGE("Unable to connect to ANT Server Socket!!!"); 1035 else 1036 ALOGE("Unable to connect to BT Server Socket!!!"); 1037 retval = -1; 1038 } 1039 } 1040 } else { 1041 if (q->soc_type == BT_SOC_ROME) 1042 ALOGE("Failed to initialize ROME Controller!!!"); 1043 } 1044 1045 if (fd >= 0) { 1046 userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 1047 /*Close the UART port*/ 1048 close(fd); 1049 } 1050 } 1051 break; 1052 case BT_SOC_CHEROKEE: 1053 { 1054 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 1055 retval = start_hci_filter(); 1056 if (retval < 0) { 1057 ALOGE("WCNSS_FILTER wouldn't have started in time\n"); 1058 1059 } else { 1060 #ifdef ENABLE_ANT 1061 if (is_ant_req) { 1062 ALOGI("%s: connect to ant channel", __func__); 1063 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 1064 } 1065 else 1066 #endif 1067 #ifdef FM_OVER_UART 1068 if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) { 1069 ALOGI("%s: connect to fm channel", __func__); 1070 q->fm_fd = fd_filter = connect_to_local_socket("fm_sock"); 1071 } 1072 else 1073 #endif 1074 { 1075 ALOGI("%s: connect to bt channel", __func__); 1076 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 1077 1078 } 1079 if (fd_filter != -1) { 1080 ALOGV("%s: received the socket fd: %d \n", 1081 __func__, fd_filter); 1082 1083 for (idx=0; idx < CH_MAX; idx++) { 1084 (*fd_array)[idx] = fd_filter; 1085 } 1086 retval = 1; 1087 } 1088 else { 1089 #ifdef ENABLE_ANT 1090 if (is_ant_req) 1091 ALOGE("Unable to connect to ANT Server Socket!!!"); 1092 else 1093 #endif 1094 #ifdef FM_OVER_UART 1095 if (is_fm_req) 1096 ALOGE("Unable to connect to FM Server Socket!!!"); 1097 else 1098 #endif 1099 ALOGE("Unable to connect to BT Server Socket!!!"); 1100 retval = -1; 1101 } 1102 } 1103 } 1104 break; 1105 default: 1106 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1107 break; 1108 } 1109 } break; 1110 #ifdef ENABLE_ANT 1111 case BT_VND_OP_ANT_USERIAL_CLOSE: 1112 { 1113 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE"); 1114 property_set("wc_transport.clean_up","1"); 1115 if (q->ant_fd != -1) { 1116 ALOGE("closing ant_fd"); 1117 close(q->ant_fd); 1118 q->ant_fd = -1; 1119 } 1120 } 1121 break; 1122 #endif 1123 #ifdef FM_OVER_UART 1124 case BT_VND_OP_FM_USERIAL_CLOSE: 1125 { 1126 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE"); 1127 property_set("wc_transport.clean_up","1"); 1128 if (q->fm_fd != -1) { 1129 ALOGE("closing fm_fd"); 1130 close(q->fm_fd); 1131 q->fm_fd = -1; 1132 } 1133 break; 1134 } 1135 #endif 1136 case BT_VND_OP_USERIAL_CLOSE: 1137 { 1138 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type); 1139 switch(q->soc_type) 1140 { 1141 case BT_SOC_DEFAULT: 1142 bt_hci_deinit_transport(q->fd); 1143 break; 1144 case BT_SOC_ROME: 1145 case BT_SOC_AR3K: 1146 case BT_SOC_CHEROKEE: 1147 { 1148 property_set("wc_transport.clean_up","1"); 1149 userial_vendor_close(); 1150 break; 1151 } 1152 default: 1153 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1154 break; 1155 } 1156 } 1157 break; 1158 1159 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 1160 { 1161 if (!param) { 1162 ALOGE("opcode = %d: param is null", opcode_init); 1163 break; 1164 } 1165 uint32_t *timeout_ms = (uint32_t *) param; 1166 *timeout_ms = 1000; 1167 } 1168 1169 break; 1170 1171 case BT_VND_OP_LPM_SET_MODE: 1172 if (q->soc_type == BT_SOC_AR3K) { 1173 if (!param) { 1174 ALOGE("opcode = %d: param is null", opcode_init); 1175 break; 1176 } 1177 uint8_t *mode = (uint8_t *) param; 1178 1179 if (*mode) { 1180 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0); 1181 } 1182 else { 1183 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 1184 } 1185 q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS); 1186 } else { 1187 int lpm_result = BT_VND_OP_RESULT_SUCCESS; 1188 1189 property_get("persist.service.bdroid.lpmcfg", lpm_config, "all"); 1190 ALOGI("%s: property_get: persist.service.bdroid.lpmcfg: %s", 1191 __func__, lpm_config); 1192 1193 if (!strcmp(lpm_config, "all")) { 1194 // respond with success since we want to hold wake lock through LPM 1195 lpm_result = BT_VND_OP_RESULT_SUCCESS; 1196 } 1197 else { 1198 lpm_result = BT_VND_OP_RESULT_FAIL; 1199 } 1200 1201 q->cb->lpm_cb(lpm_result); 1202 } 1203 break; 1204 1205 case BT_VND_OP_LPM_WAKE_SET_STATE: { 1206 switch(q->soc_type) { 1207 case BT_SOC_CHEROKEE: 1208 case BT_SOC_ROME: { 1209 if (!param) { 1210 ALOGE("opcode = %d: param is null", opcode_init); 1211 break; 1212 } 1213 uint8_t *state = (uint8_t *) param; 1214 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 1215 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT; 1216 1217 if (wake_assert == 0) 1218 ALOGV("ASSERT: Waking up BT-Device"); 1219 else if (wake_assert == 1) 1220 ALOGV("DEASSERT: Allowing BT-Device to Sleep"); 1221 1222 #ifdef QCOM_BT_SIBS_ENABLE 1223 ALOGI("Invoking HCI H4 callback function"); 1224 q->cb->lpm_set_state_cb(wake_assert); 1225 #endif 1226 } 1227 break; 1228 case BT_SOC_AR3K: { 1229 if (!param) { 1230 ALOGE("opcode = %d: param is null", opcode_init); 1231 break; 1232 } 1233 uint8_t *state = (uint8_t *) param; 1234 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 1235 UPIO_ASSERT : UPIO_DEASSERT; 1236 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0); 1237 } 1238 case BT_SOC_DEFAULT: 1239 break; 1240 default: 1241 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1242 break; 1243 } 1244 } 1245 break; 1246 case BT_VND_OP_EPILOG: { 1247 #if (HW_NEED_END_WITH_HCI_RESET == FALSE) 1248 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1249 #else 1250 switch(q->soc_type) 1251 { 1252 case BT_SOC_CHEROKEE: 1253 case BT_SOC_ROME: 1254 { 1255 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1256 property_get("wc_transport.hci_filter_status", value, "0"); 1257 if(is_soc_initialized()&& (strcmp(value,"1") == 0)) 1258 { 1259 __hw_epilog_process(); 1260 } 1261 else 1262 { 1263 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1264 } 1265 } 1266 break; 1267 default: 1268 __hw_epilog_process(); 1269 break; 1270 } 1271 #endif 1272 } 1273 break; 1274 case BT_VND_OP_GET_LINESPEED: 1275 { 1276 retval = -1; 1277 if(!is_soc_initialized()) { 1278 ALOGE("BT_VND_OP_GET_LINESPEED: error" 1279 " - transport driver not initialized!"); 1280 break; 1281 } 1282 1283 switch(q->soc_type) 1284 { 1285 case BT_SOC_CHEROKEE: 1286 retval = 3200000; 1287 break; 1288 case BT_SOC_ROME: 1289 retval = 3000000; 1290 break; 1291 default: 1292 retval = userial_vendor_get_baud(); 1293 break; 1294 } 1295 break; 1296 } 1297 } 1298 1299 out: 1300 ALOGV("--%s", __FUNCTION__); 1301 return retval; 1302 } 1303 1304 static int op(bt_vendor_opcode_t opcode, void *param) 1305 { 1306 int ret; 1307 ALOGV("++%s", __FUNCTION__); 1308 #ifdef BT_THREADLOCK_SAFE 1309 pthread_mutex_lock(&q_lock); 1310 #endif 1311 if (!q) { 1312 ALOGE("op called with NULL context"); 1313 ret = -BT_STATUS_INVAL; 1314 goto out; 1315 } 1316 ret = __op(opcode, param); 1317 out: 1318 #ifdef BT_THREADLOCK_SAFE 1319 pthread_mutex_unlock(&q_lock); 1320 #endif 1321 ALOGV("--%s ret = 0x%x", __FUNCTION__, ret); 1322 return ret; 1323 } 1324 1325 static void ssr_cleanup(int reason) 1326 { 1327 int pwr_state = BT_VND_PWR_OFF; 1328 int ret; 1329 unsigned char trig_ssr = 0xEE; 1330 1331 ALOGI("++%s", __FUNCTION__); 1332 1333 pthread_mutex_lock(&q_lock); 1334 if (!q) { 1335 ALOGE("ssr_cleanup called with NULL context"); 1336 goto out; 1337 } 1338 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 1339 ALOGE("Failed to set property"); 1340 } 1341 1342 if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) { 1343 #ifdef ENABLE_ANT 1344 /*Indicate to filter by sending special byte */ 1345 if (reason == CMD_TIMEOUT) { 1346 trig_ssr = 0xEE; 1347 ret = write (vnd_userial.fd, &trig_ssr, 1); 1348 ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s", 1349 ret, strerror(errno)); 1350 1351 if (is_debug_force_special_bytes()) { 1352 /* 1353 * Then we should send special byte to crash SOC in 1354 * WCNSS_Filter, so we do not need to power off UART here. 1355 */ 1356 goto out; 1357 } 1358 } 1359 1360 /* Close both ANT channel */ 1361 __op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL); 1362 #endif 1363 /* Close both BT channel */ 1364 __op(BT_VND_OP_USERIAL_CLOSE, NULL); 1365 1366 #ifdef FM_OVER_UART 1367 __op(BT_VND_OP_FM_USERIAL_CLOSE, NULL); 1368 #endif 1369 /*CTRL OFF twice to make sure hw 1370 * turns off*/ 1371 #ifdef ENABLE_ANT 1372 __op(BT_VND_OP_POWER_CTRL, &pwr_state); 1373 #endif 1374 } 1375 /*Generally switching of chip should be enough*/ 1376 __op(BT_VND_OP_POWER_CTRL, &pwr_state); 1377 1378 out: 1379 pthread_mutex_unlock(&q_lock); 1380 ALOGI("--%s", __FUNCTION__); 1381 } 1382 1383 /** Closes the interface */ 1384 static void cleanup(void) 1385 { 1386 ALOGI("cleanup"); 1387 1388 pthread_mutex_lock(&q_lock); 1389 q->cb = NULL; 1390 free(q); 1391 q = NULL; 1392 pthread_mutex_unlock(&q_lock); 1393 1394 #ifdef WIFI_BT_STATUS_SYNC 1395 isInit = 0; 1396 #endif /* WIFI_BT_STATUS_SYNC */ 1397 } 1398 1399 /* Check for one of the cients ANT/BT patch download is already in 1400 ** progress if yes wait till complete 1401 */ 1402 void wait_for_patch_download(bool is_ant_req) { 1403 ALOGV("%s:", __FUNCTION__); 1404 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 1405 while (1) { 1406 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 1407 1408 if(is_ant_req && !(strcmp(inProgress,"bt"))) { 1409 //ANT request, wait for BT to finish 1410 usleep(50000); 1411 } 1412 else if(!is_ant_req && !(strcmp(inProgress,"ant"))) { 1413 //BT request, wait for ANT to finish 1414 usleep(50000); 1415 } 1416 else { 1417 ALOGI("%s: patch download completed", __FUNCTION__); 1418 break; 1419 } 1420 } 1421 } 1422 1423 bool is_download_progress () { 1424 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 1425 bool retval = false; 1426 1427 ALOGV("%s:", __FUNCTION__); 1428 1429 if ((q->soc_type = get_bt_soc_type()) < 0) { 1430 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 1431 return -1; 1432 } 1433 1434 switch(q->soc_type) 1435 { 1436 case BT_SOC_ROME: 1437 ALOGI("%s: ROME case", __func__); 1438 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 1439 if(strcmp(inProgress,"null") == 0) { 1440 retval = false; 1441 } else { 1442 retval = true; 1443 } 1444 break; 1445 case BT_SOC_CHEROKEE: 1446 ALOGI("%s: CHEROKEE case", __func__); 1447 break; 1448 case BT_SOC_DEFAULT: 1449 break; 1450 default: 1451 ALOGE("Unknown btSocType: 0x%x", q->soc_type); 1452 break; 1453 } 1454 return retval; 1455 } 1456 1457 static bool is_debug_force_special_bytes() { 1458 int ret = 0; 1459 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1460 bool enabled = false; 1461 #ifdef ENABLE_DBG_FLAGS 1462 enabled = true; 1463 #endif 1464 1465 ret = property_get("wc_transport.force_special_byte", value, NULL); 1466 1467 if (ret) { 1468 enabled = (strcmp(value, "false") ==0) ? false : true; 1469 ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ", 1470 __func__, value, enabled); 1471 } 1472 1473 return enabled; 1474 } 1475 1476 // Entry point of DLib 1477 /* Remove 'ssr_cleanup' because it's not defined in 'bt_vendor_interface_t'. */ 1478 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 1479 sizeof(bt_vendor_interface_t), 1480 init, 1481 op, 1482 cleanup 1483 }; 1484