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