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