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 property_set("wc_transport.clean_up","0"); 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 if(can_perform_action(on) == false) { 455 ALOGE("%s:can't perform action as it is being used by other clients", __func__); 456 #ifdef WIFI_BT_STATUS_SYNC 457 bt_semaphore_release(lock_fd); 458 bt_semaphore_destroy(lock_fd); 459 #endif 460 goto done; 461 } 462 ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id); 463 if( (ret < 0 ) || (enable_ldo_path == NULL) ) 464 { 465 ALOGE("Memory Allocation failure"); 466 return -1; 467 } 468 if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) { 469 ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 470 return -1; 471 } 472 size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo)); 473 close(fd_ldo); 474 if (size <= 0) { 475 ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 476 return -1; 477 } 478 if (!memcmp(enable_ldo, "true", 4)) { 479 ALOGI("External LDO has been configured"); 480 ret = property_set("wc_transport.extldo", "enabled"); 481 if (ret < 0) { 482 ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__); 483 } 484 q->enable_extldo = TRUE; 485 } 486 487 if(on == '0'){ 488 ALOGE("Stopping HCI filter as part of CTRL:OFF"); 489 stop_hci_filter(); 490 property_set("wc_transport.soc_initialized", "0"); 491 } 492 493 if (q->soc_type >= BT_SOC_CHEROKEE && q->soc_type < BT_SOC_RESERVED) { 494 ALOGI("open bt power devnode,send ioctl power op :%d ",en); 495 fd_btpower = open(BT_PWR_CNTRL_DEVICE, O_RDWR, O_NONBLOCK); 496 if (fd_btpower < 0) { 497 ALOGE("\nfailed to open bt device error = (%s)\n",strerror(errno)); 498 #ifdef WIFI_BT_STATUS_SYNC 499 bt_semaphore_release(lock_fd); 500 bt_semaphore_destroy(lock_fd); 501 #endif 502 return -1; 503 } 504 ret = ioctl(fd_btpower, BT_CMD_PWR_CTRL, (unsigned long)en); 505 if (ret < 0) { 506 ALOGE(" ioctl failed to power control:%d error =(%s)",ret,strerror(errno)); 507 } 508 close(fd_btpower); 509 } else { 510 ALOGI("Write %c to rfkill\n", on); 511 /* Write value to control rfkill */ 512 if(fd >= 0) { 513 if ((size = write(fd, &on, 1)) < 0) { 514 ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno); 515 #ifdef WIFI_BT_STATUS_SYNC 516 bt_semaphore_release(lock_fd); 517 bt_semaphore_destroy(lock_fd); 518 #endif 519 return -1; 520 } 521 } 522 } 523 #ifdef WIFI_BT_STATUS_SYNC 524 /* query wifi status */ 525 property_get(WIFI_PROP_NAME, wifi_status, ""); 526 527 ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit); 528 529 /* If wlan driver is not loaded, and bt is changed from off => on */ 530 if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) { 531 if (on == '1') { 532 ALOGI("%s: BT_VND_PWR_ON\n", __func__); 533 if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) { 534 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 535 close(fd); 536 bt_semaphore_release(lock_fd); 537 bt_semaphore_destroy(lock_fd); 538 return -1; 539 } 540 } 541 else if (isInit == 0 && on == '0') { 542 ALOGI("%s: BT_VND_PWR_OFF\n", __func__); 543 if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) { 544 ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 545 close(fd); 546 bt_semaphore_release(lock_fd); 547 bt_semaphore_destroy(lock_fd); 548 return -1; 549 } 550 } 551 } 552 553 if (isInit == 0 && on == '0') 554 property_set(BT_STATUS_NAME, "false"); 555 else if (on == '1') 556 property_set(BT_STATUS_NAME, "true"); 557 558 bt_semaphore_release(lock_fd); 559 bt_semaphore_destroy(lock_fd); 560 #endif /* WIFI_BT_STATUS_SYNC */ 561 562 done: 563 if (fd >= 0) 564 close(fd); 565 return 0; 566 } 567 568 static inline void soc_init(int soc_type) 569 { 570 switch (soc_type) 571 { 572 case BT_SOC_CHEROKEE: 573 case BT_SOC_ROME: 574 case BT_SOC_AR3K: 575 ALOGI("bt-vendor : Initializing UART transport layer"); 576 userial_vendor_init(); 577 break; 578 case BT_SOC_DEFAULT: 579 break; 580 default: 581 ALOGE("Unknown soc yype: %d", soc_type); 582 break; 583 } 584 } 585 586 /* Copy BD Address as little-endian byte order */ 587 static inline void le2bd(unsigned char *src, unsigned char *dst) 588 { 589 int i; 590 for (i = 0; i < 6; i++) 591 dst[i] = src[5-i]; 592 } 593 594 static inline void print_bdaddr(unsigned char *addr) 595 { 596 ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1], 597 addr[2], addr[3], addr[4], addr[5]); 598 } 599 600 /***************************************************************************** 601 ** 602 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 603 ** 604 *****************************************************************************/ 605 606 static int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr) 607 { 608 char prop[PROPERTY_VALUE_MAX] = {0}; 609 struct bt_qcom_struct *temp = NULL; 610 int ret = BT_STATUS_SUCCESS, i; 611 612 ALOGI("++%s", __FUNCTION__); 613 614 if (!cb || !bdaddr) { 615 ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr); 616 ret = -BT_STATUS_INVAL; 617 goto out; 618 } 619 620 temp = (struct bt_qcom_struct *) malloc(sizeof(*q)); 621 if (!temp) { 622 ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno); 623 ret = -BT_STATUS_NOMEM; 624 goto out; 625 } 626 memset(temp, 0, sizeof(*temp)); 627 628 temp->rfkill_id = -1; 629 temp->enable_extldo = FALSE; 630 temp->cb = (bt_vendor_callbacks_t*)cb; 631 temp->ant_fd = -1; 632 temp->soc_type = get_bt_soc_type(); 633 soc_init(temp->soc_type); 634 635 le2bd(bdaddr, temp->bdaddr); 636 print_bdaddr(temp->bdaddr); 637 snprintf(prop, sizeof(prop), "%02x:%02x:%02x:%02x:%02x:%02x", 638 temp->bdaddr[0], temp->bdaddr[1], temp->bdaddr[2], 639 temp->bdaddr[3], temp->bdaddr[4], temp->bdaddr[5]); 640 ret = property_set("wc_transport.stack_bdaddr", prop); 641 if (ret < 0) { 642 ALOGE("Failed to set wc_transport.stack_bdaddr prop, ret = %d", ret); 643 ret = -BT_STATUS_PROP_FAILURE; 644 goto out; 645 } 646 647 /* TODO: Move these fields inside bt_qcom context */ 648 #ifdef WIFI_BT_STATUS_SYNC 649 isInit = 1; 650 #endif /* WIFI_BT_STATUS_SYNC */ 651 652 /* Everything successful */ 653 q = temp; 654 return ret; 655 656 out: 657 if (temp) 658 free(temp); 659 ALOGI("--%s ret %d", __FUNCTION__, ret); 660 return ret; 661 } 662 663 #ifdef READ_BT_ADDR_FROM_PROP 664 static bool validate_tok(char* bdaddr_tok) { 665 int i = 0; 666 bool ret; 667 668 if (strlen(bdaddr_tok) != 2) { 669 ret = FALSE; 670 ALOGE("Invalid token length"); 671 } else { 672 ret = TRUE; 673 for (i=0; i<2; i++) { 674 if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') || 675 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') || 676 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) { 677 ret = TRUE; 678 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i); 679 } else { 680 ret = FALSE; 681 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i); 682 break; 683 } 684 } 685 } 686 return ret; 687 } 688 #endif /*READ_BT_ADDR_FROM_PROP*/ 689 690 int connect_to_local_socket(char* name) { 691 socklen_t len; int sk = -1; 692 693 ALOGE("%s: ACCEPT ", __func__); 694 sk = socket(AF_LOCAL, SOCK_STREAM, 0); 695 if (sk < 0) { 696 ALOGE("Socket creation failure"); 697 return -1; 698 } 699 700 if(socket_local_client_connect(sk, name, 701 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) 702 { 703 ALOGE("failed to connect (%s)", strerror(errno)); 704 close(sk); 705 sk = -1; 706 } else { 707 ALOGE("%s: Connection succeeded\n", __func__); 708 } 709 return sk; 710 } 711 712 bool is_soc_initialized() { 713 bool init = false; 714 char init_value[PROPERTY_VALUE_MAX]; 715 int ret; 716 717 ALOGI("bt-vendor : is_soc_initialized"); 718 719 ret = property_get(SOC_INIT_PROPERTY, init_value, NULL); 720 if (ret != 0) { 721 ALOGI("%s set to %s\n", SOC_INIT_PROPERTY, init_value); 722 if (!strncasecmp(init_value, "1", sizeof("1"))) { 723 init = true; 724 } 725 } 726 else { 727 ALOGE("%s: Failed to get %s", __FUNCTION__, SOC_INIT_PROPERTY); 728 } 729 730 return init; 731 } 732 733 /* flavor of op without locks */ 734 static int op(bt_vendor_opcode_t opcode, void *param) 735 { 736 int retval = BT_STATUS_SUCCESS; 737 int nCnt = 0; 738 int nState = -1; 739 bool is_ant_req = false; 740 bool is_fm_req = false; 741 char wipower_status[PROPERTY_VALUE_MAX]; 742 char emb_wp_mode[PROPERTY_VALUE_MAX]; 743 char bt_version[PROPERTY_VALUE_MAX]; 744 char lpm_config[PROPERTY_VALUE_MAX]; 745 bool ignore_boot_prop = TRUE; 746 #ifdef READ_BT_ADDR_FROM_PROP 747 int i = 0; 748 static char bd_addr[PROPERTY_VALUE_MAX]; 749 uint8_t local_bd_addr_from_prop[6]; 750 char* tok; 751 #endif 752 bool skip_init = true; 753 int opcode_init = opcode; 754 ALOGV("++%s opcode %d", __FUNCTION__, opcode); 755 756 switch(opcode_init) 757 { 758 #ifdef FM_OVER_UART 759 case FM_VND_OP_POWER_CTRL: 760 { 761 is_fm_req = true; 762 if (is_soc_initialized()) { 763 // add any FM specific actions if needed in future 764 break; 765 } 766 } 767 #endif 768 case BT_VND_OP_POWER_CTRL: 769 { 770 if (!param) { 771 ALOGE("opcode = %d: param is null", opcode_init); 772 break; 773 } 774 nState = *(int *) param; 775 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s", 776 (nState == BT_VND_PWR_ON)? "On" : "Off" ); 777 778 switch(q->soc_type) 779 { 780 case BT_SOC_DEFAULT: 781 if (readTrpState()) 782 { 783 ALOGI("bt-vendor : resetting BT status"); 784 hw_config(BT_VND_PWR_OFF); 785 } 786 retval = hw_config(nState); 787 if(nState == BT_VND_PWR_ON 788 && retval == 0 789 && is_hw_ready() == TRUE){ 790 retval = 0; 791 } 792 else { 793 retval = -1; 794 } 795 break; 796 case BT_SOC_ROME: 797 case BT_SOC_AR3K: 798 case BT_SOC_CHEROKEE: 799 /* BT Chipset Power Control through Device Tree Node */ 800 retval = bt_powerup(nState); 801 default: 802 break; 803 } 804 } 805 break; 806 807 case BT_VND_OP_FW_CFG: { 808 /* call hciattach to initalize the stack */ 809 if (q->soc_type == BT_SOC_ROME) { 810 if (is_soc_initialized()) { 811 ALOGI("Bluetooth FW and transport layer are initialized"); 812 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 813 } else { 814 ALOGE("bt_vendor_cbacks is null or SoC not initialized"); 815 ALOGE("Error : hci, smd initialization Error"); 816 retval = -1; 817 } 818 } else { 819 ALOGI("Bluetooth FW and transport layer are initialized"); 820 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 821 } 822 } 823 break; 824 825 case BT_VND_OP_SCO_CFG: 826 q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 827 break; 828 #ifdef ENABLE_ANT 829 case BT_VND_OP_ANT_USERIAL_OPEN: 830 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN"); 831 is_ant_req = true; 832 goto userial_open; 833 #endif 834 #ifdef FM_OVER_UART 835 case BT_VND_OP_FM_USERIAL_OPEN: 836 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_OPEN"); 837 is_fm_req = true; 838 goto userial_open; 839 #endif 840 userial_open: 841 case BT_VND_OP_USERIAL_OPEN: 842 { 843 if (!param) { 844 ALOGE("opcode = %d: param is null", opcode_init); 845 break; 846 } 847 int (*fd_array)[] = (int (*)[]) param; 848 int idx, fd = -1, fd_filter = -1; 849 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN"); 850 switch(q->soc_type) 851 { 852 case BT_SOC_DEFAULT: 853 { 854 if(bt_hci_init_transport(q->fd) != -1){ 855 int (*fd_array)[] = (int (*) []) param; 856 857 (*fd_array)[CH_CMD] = q->fd[0]; 858 (*fd_array)[CH_EVT] = q->fd[0]; 859 (*fd_array)[CH_ACL_OUT] = q->fd[1]; 860 (*fd_array)[CH_ACL_IN] = q->fd[1]; 861 } 862 else { 863 retval = -1; 864 break; 865 } 866 retval = 2; 867 } 868 break; 869 case BT_SOC_AR3K: 870 { 871 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 872 if (fd != -1) { 873 for (idx=0; idx < CH_MAX; idx++) 874 (*fd_array)[idx] = fd; 875 retval = 1; 876 } 877 else { 878 retval = -1; 879 break; 880 } 881 882 /* Vendor Specific Process should happened during userial_open process 883 After userial_open, rx read thread is running immediately, 884 so it will affect VS event read process. 885 */ 886 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0) 887 retval = -1; 888 } 889 break; 890 case BT_SOC_ROME: 891 { 892 wait_for_patch_download(is_ant_req); 893 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 894 if (!is_soc_initialized()) { 895 char* dlnd_inprog = is_ant_req ? "ant" : "bt"; 896 if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) { 897 ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog); 898 } 899 900 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 901 if (fd < 0) { 902 ALOGE("userial_vendor_open returns err"); 903 retval = -1; 904 break; 905 } 906 907 /* Clock on */ 908 userial_clock_operation(fd, USERIAL_OP_CLK_ON); 909 910 if(strcmp(emb_wp_mode, "true") == 0) { 911 property_get("ro.bluetooth.wipower", wipower_status, false); 912 if(strcmp(wipower_status, "true") == 0) { 913 check_embedded_mode(fd); 914 } else { 915 ALOGI("Wipower not enabled"); 916 } 917 } 918 ALOGV("rome_soc_init is started"); 919 property_set("wc_transport.soc_initialized", "0"); 920 #ifdef READ_BT_ADDR_FROM_PROP 921 /*Give priority to read BD address from boot property*/ 922 ignore_boot_prop = FALSE; 923 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) { 924 ALOGV("BD address read from Boot property: %s\n", bd_addr); 925 tok = strtok(bd_addr, ":"); 926 while (tok != NULL) { 927 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16)); 928 if (i>=6) { 929 ALOGE("bd property of invalid length"); 930 ignore_boot_prop = TRUE; 931 break; 932 } 933 if (i == 6 && !ignore_boot_prop) { 934 ALOGV("Valid BD address read from prop"); 935 memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 936 ignore_boot_prop = FALSE; 937 } else { 938 ALOGE("There are not enough tokens in BD addr"); 939 ignore_boot_prop = TRUE; 940 break; 941 } 942 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16); 943 tok = strtok(NULL, ":"); 944 i++; 945 } 946 if (i == 6 && !ignore_boot_prop) { 947 ALOGV("Valid BD address read from prop"); 948 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 949 ignore_boot_prop = FALSE; 950 } else { 951 ALOGE("There are not enough tokens in BD addr"); 952 ignore_boot_prop = TRUE; 953 } 954 } 955 else { 956 ALOGE("BD address boot property not set"); 957 ignore_boot_prop = TRUE; 958 } 959 #endif //READ_BT_ADDR_FROM_PROP 960 #ifdef BT_NV_SUPPORT 961 /* Always read BD address from NV file */ 962 if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr)) 963 { 964 /* Since the BD address is configured in boot time We should not be here */ 965 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm"); 966 } 967 #endif //BT_NV_SUPPORT 968 if(rome_soc_init(fd, (char*)q->bdaddr)<0) { 969 retval = -1; 970 } else { 971 ALOGV("rome_soc_init is completed"); 972 property_set("wc_transport.soc_initialized", "1"); 973 skip_init = false; 974 } 975 } 976 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 977 ALOGE("%s: Failed to set property", __FUNCTION__); 978 } 979 980 property_set("wc_transport.clean_up","0"); 981 if (retval != -1) { 982 983 retval = start_hci_filter(); 984 if (retval < 0) { 985 ALOGE("%s: WCNSS_FILTER wouldn't have started in time\n", __func__); 986 } else { 987 #ifdef ENABLE_ANT 988 if (is_ant_req) { 989 ALOGI("%s: connect to ant channel", __func__); 990 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 991 } 992 else 993 #endif 994 { 995 ALOGI("%s: connect to bt channel", __func__); 996 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 997 } 998 999 if (fd_filter != -1) { 1000 ALOGI("%s: received the socket fd: %d is_ant_req: %d is_fm_req: %d\n", 1001 __func__, fd_filter, is_ant_req,is_fm_req); 1002 if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req && !is_fm_req) { 1003 if (chipset_ver >= ROME_VER_3_0) { 1004 /* get rome supported feature request */ 1005 ALOGE("%s: %x08 %0x", __FUNCTION__,chipset_ver, ROME_VER_3_0); 1006 rome_get_addon_feature_list(fd_filter); 1007 } 1008 } 1009 if (!skip_init) { 1010 /*Skip if already sent*/ 1011 enable_controller_log(fd_filter, (is_ant_req || is_fm_req) ); 1012 skip_init = true; 1013 } 1014 for (idx=0; idx < CH_MAX; idx++) 1015 (*fd_array)[idx] = fd_filter; 1016 retval = 1; 1017 } 1018 else { 1019 if (is_ant_req) 1020 ALOGE("Unable to connect to ANT Server Socket!!!"); 1021 else 1022 ALOGE("Unable to connect to BT Server Socket!!!"); 1023 retval = -1; 1024 } 1025 } 1026 } else { 1027 if (q->soc_type == BT_SOC_ROME) 1028 ALOGE("Failed to initialize ROME Controller!!!"); 1029 } 1030 1031 if (fd >= 0) { 1032 userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 1033 /*Close the UART port*/ 1034 close(fd); 1035 } 1036 } 1037 break; 1038 case BT_SOC_CHEROKEE: 1039 { 1040 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 1041 retval = start_hci_filter(); 1042 if (retval < 0) { 1043 ALOGE("WCNSS_FILTER wouldn't have started in time\n"); 1044 /* 1045 Set the following property to -1 so that the SSR cleanup routine 1046 can reset SOC. 1047 */ 1048 property_set("wc_transport.hci_filter_status", "-1"); 1049 } else { 1050 #ifdef ENABLE_ANT 1051 if (is_ant_req) { 1052 ALOGI("%s: connect to ant channel", __func__); 1053 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 1054 } 1055 else 1056 #endif 1057 #ifdef FM_OVER_UART 1058 if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) { 1059 ALOGI("%s: connect to fm channel", __func__); 1060 q->fm_fd = fd_filter = connect_to_local_socket("fm_sock"); 1061 } 1062 else 1063 #endif 1064 { 1065 ALOGI("%s: connect to bt channel", __func__); 1066 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 1067 1068 } 1069 if (fd_filter != -1) { 1070 ALOGV("%s: received the socket fd: %d \n", 1071 __func__, fd_filter); 1072 1073 for (idx=0; idx < CH_MAX; idx++) { 1074 (*fd_array)[idx] = fd_filter; 1075 } 1076 retval = 1; 1077 } 1078 else { 1079 #ifdef ENABLE_ANT 1080 if (is_ant_req) 1081 ALOGE("Unable to connect to ANT Server Socket!!!"); 1082 else 1083 #endif 1084 #ifdef FM_OVER_UART 1085 if (is_fm_req) 1086 ALOGE("Unable to connect to FM Server Socket!!!"); 1087 else 1088 #endif 1089 ALOGE("Unable to connect to BT Server Socket!!!"); 1090 retval = -1; 1091 } 1092 } 1093 } 1094 break; 1095 default: 1096 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1097 break; 1098 } 1099 } break; 1100 #ifdef ENABLE_ANT 1101 case BT_VND_OP_ANT_USERIAL_CLOSE: 1102 { 1103 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE"); 1104 property_set("wc_transport.clean_up","1"); 1105 if (q->ant_fd != -1) { 1106 ALOGE("closing ant_fd"); 1107 close(q->ant_fd); 1108 q->ant_fd = -1; 1109 } 1110 } 1111 break; 1112 #endif 1113 #ifdef FM_OVER_UART 1114 case BT_VND_OP_FM_USERIAL_CLOSE: 1115 { 1116 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE"); 1117 property_set("wc_transport.clean_up","1"); 1118 if (q->fm_fd != -1) { 1119 ALOGE("closing fm_fd"); 1120 close(q->fm_fd); 1121 q->fm_fd = -1; 1122 } 1123 break; 1124 } 1125 #endif 1126 case BT_VND_OP_USERIAL_CLOSE: 1127 { 1128 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type); 1129 switch(q->soc_type) 1130 { 1131 case BT_SOC_DEFAULT: 1132 bt_hci_deinit_transport(q->fd); 1133 break; 1134 case BT_SOC_ROME: 1135 case BT_SOC_AR3K: 1136 case BT_SOC_CHEROKEE: 1137 { 1138 property_set("wc_transport.clean_up","1"); 1139 userial_vendor_close(); 1140 break; 1141 } 1142 default: 1143 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1144 break; 1145 } 1146 } 1147 break; 1148 1149 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 1150 { 1151 if (!param) { 1152 ALOGE("opcode = %d: param is null", opcode_init); 1153 break; 1154 } 1155 uint32_t *timeout_ms = (uint32_t *) param; 1156 *timeout_ms = 1000; 1157 } 1158 1159 break; 1160 1161 case BT_VND_OP_LPM_SET_MODE: 1162 if (q->soc_type == BT_SOC_AR3K) { 1163 if (!param) { 1164 ALOGE("opcode = %d: param is null", opcode_init); 1165 break; 1166 } 1167 uint8_t *mode = (uint8_t *) param; 1168 1169 if (*mode) { 1170 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0); 1171 } 1172 else { 1173 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 1174 } 1175 q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS); 1176 } else { 1177 int lpm_result = BT_VND_OP_RESULT_SUCCESS; 1178 1179 property_get("persist.service.bdroid.lpmcfg", lpm_config, "all"); 1180 ALOGI("%s: property_get: persist.service.bdroid.lpmcfg: %s", 1181 __func__, lpm_config); 1182 1183 if (!strcmp(lpm_config, "all")) { 1184 // respond with success since we want to hold wake lock through LPM 1185 lpm_result = BT_VND_OP_RESULT_SUCCESS; 1186 } 1187 else { 1188 lpm_result = BT_VND_OP_RESULT_FAIL; 1189 } 1190 1191 q->cb->lpm_cb(lpm_result); 1192 } 1193 break; 1194 1195 case BT_VND_OP_LPM_WAKE_SET_STATE: { 1196 switch(q->soc_type) { 1197 case BT_SOC_CHEROKEE: 1198 case BT_SOC_ROME: { 1199 if (!param) { 1200 ALOGE("opcode = %d: param is null", opcode_init); 1201 break; 1202 } 1203 uint8_t *state = (uint8_t *) param; 1204 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 1205 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT; 1206 1207 if (wake_assert == 0) 1208 ALOGV("ASSERT: Waking up BT-Device"); 1209 else if (wake_assert == 1) 1210 ALOGV("DEASSERT: Allowing BT-Device to Sleep"); 1211 1212 #ifdef QCOM_BT_SIBS_ENABLE 1213 ALOGI("Invoking HCI H4 callback function"); 1214 q->cb->lpm_set_state_cb(wake_assert); 1215 #endif 1216 } 1217 break; 1218 case BT_SOC_AR3K: { 1219 if (!param) { 1220 ALOGE("opcode = %d: param is null", opcode_init); 1221 break; 1222 } 1223 uint8_t *state = (uint8_t *) param; 1224 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 1225 UPIO_ASSERT : UPIO_DEASSERT; 1226 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0); 1227 } 1228 case BT_SOC_DEFAULT: 1229 break; 1230 default: 1231 ALOGE("Unknown soc_type: 0x%x", q->soc_type); 1232 break; 1233 } 1234 } 1235 break; 1236 case BT_VND_OP_EPILOG: { 1237 #if (HW_NEED_END_WITH_HCI_RESET == FALSE) 1238 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1239 #else 1240 switch(q->soc_type) 1241 { 1242 case BT_SOC_CHEROKEE: 1243 case BT_SOC_ROME: 1244 { 1245 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1246 property_get("wc_transport.hci_filter_status", value, "0"); 1247 if(is_soc_initialized()&& (strcmp(value,"1") == 0)) 1248 { 1249 __hw_epilog_process(); 1250 } 1251 else 1252 { 1253 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 1254 } 1255 } 1256 break; 1257 default: 1258 __hw_epilog_process(); 1259 break; 1260 } 1261 #endif 1262 } 1263 break; 1264 case BT_VND_OP_GET_LINESPEED: 1265 { 1266 retval = -1; 1267 if(!is_soc_initialized()) { 1268 ALOGE("BT_VND_OP_GET_LINESPEED: error" 1269 " - transport driver not initialized!"); 1270 break; 1271 } 1272 1273 switch(q->soc_type) 1274 { 1275 case BT_SOC_CHEROKEE: 1276 retval = 3200000; 1277 break; 1278 case BT_SOC_ROME: 1279 retval = 3000000; 1280 break; 1281 default: 1282 retval = userial_vendor_get_baud(); 1283 break; 1284 } 1285 break; 1286 } 1287 } 1288 1289 out: 1290 ALOGV("--%s", __FUNCTION__); 1291 return retval; 1292 } 1293 1294 static void ssr_cleanup(int reason) 1295 { 1296 int pwr_state = BT_VND_PWR_OFF; 1297 int ret; 1298 unsigned char trig_ssr = 0xEE; 1299 #ifndef ENABLE_ANT 1300 (void)reason; // unused 1301 #endif 1302 1303 ALOGI("++%s", __FUNCTION__); 1304 1305 pthread_mutex_lock(&q_lock); 1306 if (!q) { 1307 ALOGE("ssr_cleanup called with NULL context"); 1308 goto out; 1309 } 1310 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 1311 ALOGE("Failed to set property"); 1312 } 1313 1314 if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) { 1315 #ifdef ENABLE_ANT 1316 /*Indicate to filter by sending special byte */ 1317 if (reason == CMD_TIMEOUT) { 1318 trig_ssr = 0xEE; 1319 ret = write (vnd_userial.fd, &trig_ssr, 1); 1320 ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s", 1321 ret, strerror(errno)); 1322 1323 if (is_debug_force_special_bytes()) { 1324 /* 1325 * Then we should send special byte to crash SOC in 1326 * WCNSS_Filter, so we do not need to power off UART here. 1327 */ 1328 goto out; 1329 } 1330 } 1331 1332 /* Close both ANT channel */ 1333 op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL); 1334 #endif 1335 /* Close both BT channel */ 1336 op(BT_VND_OP_USERIAL_CLOSE, NULL); 1337 1338 #ifdef FM_OVER_UART 1339 op(BT_VND_OP_FM_USERIAL_CLOSE, NULL); 1340 #endif 1341 /*CTRL OFF twice to make sure hw 1342 * turns off*/ 1343 #ifdef ENABLE_ANT 1344 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1345 #endif 1346 } 1347 /*Generally switching of chip should be enough*/ 1348 op(BT_VND_OP_POWER_CTRL, &pwr_state); 1349 1350 out: 1351 pthread_mutex_unlock(&q_lock); 1352 ALOGI("--%s", __FUNCTION__); 1353 } 1354 1355 /** Closes the interface */ 1356 static void cleanup(void) 1357 { 1358 ALOGI("cleanup"); 1359 1360 pthread_mutex_lock(&q_lock); 1361 q->cb = NULL; 1362 free(q); 1363 q = NULL; 1364 pthread_mutex_unlock(&q_lock); 1365 1366 #ifdef WIFI_BT_STATUS_SYNC 1367 isInit = 0; 1368 #endif /* WIFI_BT_STATUS_SYNC */ 1369 } 1370 1371 /* Check for one of the cients ANT/BT patch download is already in 1372 ** progress if yes wait till complete 1373 */ 1374 void wait_for_patch_download(bool is_ant_req) { 1375 ALOGV("%s:", __FUNCTION__); 1376 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 1377 while (1) { 1378 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 1379 1380 if(is_ant_req && !(strcmp(inProgress,"bt"))) { 1381 //ANT request, wait for BT to finish 1382 usleep(50000); 1383 } 1384 else if(!is_ant_req && !(strcmp(inProgress,"ant"))) { 1385 //BT request, wait for ANT to finish 1386 usleep(50000); 1387 } 1388 else { 1389 ALOGI("%s: patch download completed", __FUNCTION__); 1390 break; 1391 } 1392 } 1393 } 1394 1395 bool is_download_progress () { 1396 char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 1397 bool retval = false; 1398 1399 ALOGV("%s:", __FUNCTION__); 1400 1401 if ((q->soc_type = get_bt_soc_type()) < 0) { 1402 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 1403 return -1; 1404 } 1405 1406 switch(q->soc_type) 1407 { 1408 case BT_SOC_ROME: 1409 ALOGI("%s: ROME case", __func__); 1410 property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 1411 if(strcmp(inProgress,"null") == 0) { 1412 retval = false; 1413 } else { 1414 retval = true; 1415 } 1416 break; 1417 case BT_SOC_CHEROKEE: 1418 ALOGI("%s: CHEROKEE case", __func__); 1419 break; 1420 case BT_SOC_DEFAULT: 1421 break; 1422 default: 1423 ALOGE("Unknown btSocType: 0x%x", q->soc_type); 1424 break; 1425 } 1426 return retval; 1427 } 1428 1429 static bool is_debug_force_special_bytes() { 1430 int ret = 0; 1431 char value[PROPERTY_VALUE_MAX] = {'\0'}; 1432 bool enabled = false; 1433 #ifdef ENABLE_DBG_FLAGS 1434 enabled = true; 1435 #endif 1436 1437 ret = property_get("wc_transport.force_special_byte", value, NULL); 1438 1439 if (ret) { 1440 enabled = (strcmp(value, "false") ==0) ? false : true; 1441 ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ", 1442 __func__, value, enabled); 1443 } 1444 1445 return enabled; 1446 } 1447 1448 // Entry point of DLib 1449 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 1450 sizeof(bt_vendor_interface_t), 1451 init, 1452 op, 1453 cleanup 1454 }; 1455