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