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