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