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