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 
    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     /* Always perform BT power action so as to have the chance to
    455        recover BT power properly from un-expected error. */
    456 #ifdef CHECK_BT_POWER_PERFORM_ACTION
    457     if(can_perform_action(on) == false) {
    458         ALOGE("%s:can't perform action as it is being used by other clients", __func__);
    459 #ifdef WIFI_BT_STATUS_SYNC
    460             bt_semaphore_release(lock_fd);
    461             bt_semaphore_destroy(lock_fd);
    462 #endif
    463             goto done;
    464     }
    465 #else
    466     ALOGI("%s: always perform action", __func__);
    467 #endif
    468     ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id);
    469     if( (ret < 0 ) || (enable_ldo_path == NULL) )
    470     {
    471         ALOGE("Memory Allocation failure");
    472         return -1;
    473     }
    474     if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) {
    475         ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
    476         return -1;
    477     }
    478     size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo));
    479     close(fd_ldo);
    480     if (size <= 0) {
    481         ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
    482         return -1;
    483     }
    484     if (!memcmp(enable_ldo, "true", 4)) {
    485         ALOGI("External LDO has been configured");
    486         ret = property_set("wc_transport.extldo", "enabled");
    487         if (ret < 0) {
    488             ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__);
    489         }
    490         q->enable_extldo = TRUE;
    491     }
    492 
    493     if(on == '0'){
    494         ALOGE("Stopping HCI filter as part of CTRL:OFF");
    495         stop_hci_filter();
    496         property_set("wc_transport.soc_initialized", "0");
    497     }
    498 
    499     if (q->soc_type >= BT_SOC_CHEROKEE && q->soc_type < BT_SOC_RESERVED) {
    500        ALOGI("open bt power devnode,send ioctl power op  :%d ",en);
    501        fd_btpower = open(BT_PWR_CNTRL_DEVICE, O_RDWR, O_NONBLOCK);
    502        if (fd_btpower < 0) {
    503            ALOGE("\nfailed to open bt device error = (%s)\n",strerror(errno));
    504 #ifdef WIFI_BT_STATUS_SYNC
    505            bt_semaphore_release(lock_fd);
    506            bt_semaphore_destroy(lock_fd);
    507 #endif
    508            return -1;
    509        }
    510        ret = ioctl(fd_btpower, BT_CMD_PWR_CTRL, (unsigned long)en);
    511         if (ret < 0) {
    512             ALOGE(" ioctl failed to power control:%d error =(%s)",ret,strerror(errno));
    513         }
    514         close(fd_btpower);
    515     } else {
    516        ALOGI("Write %c to rfkill\n", on);
    517        /* Write value to control rfkill */
    518        if(fd >= 0) {
    519            if ((size = write(fd, &on, 1)) < 0) {
    520                ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno);
    521 #ifdef WIFI_BT_STATUS_SYNC
    522                bt_semaphore_release(lock_fd);
    523                bt_semaphore_destroy(lock_fd);
    524 #endif
    525                return -1;
    526            }
    527        }
    528    }
    529 #ifdef WIFI_BT_STATUS_SYNC
    530     /* query wifi status */
    531     property_get(WIFI_PROP_NAME, wifi_status, "");
    532 
    533     ALOGE("bt get wifi status: %s, isInit: %d\n",  wifi_status, isInit);
    534 
    535     /* If wlan driver is not loaded, and bt is changed from off => on */
    536     if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) {
    537         if (on == '1') {
    538             ALOGI("%s: BT_VND_PWR_ON\n", __func__);
    539             if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) {
    540                 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
    541                 close(fd);
    542                 bt_semaphore_release(lock_fd);
    543                 bt_semaphore_destroy(lock_fd);
    544                 return -1;
    545             }
    546         }
    547         else if (isInit == 0 && on == '0') {
    548             ALOGI("%s: BT_VND_PWR_OFF\n", __func__);
    549             if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) {
    550                 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
    551                 close(fd);
    552                 bt_semaphore_release(lock_fd);
    553                 bt_semaphore_destroy(lock_fd);
    554                 return -1;
    555             }
    556        }
    557     }
    558 
    559     if (isInit == 0 && on == '0')
    560         property_set(BT_STATUS_NAME, "false");
    561     else if (on == '1')
    562         property_set(BT_STATUS_NAME, "true");
    563 
    564     bt_semaphore_release(lock_fd);
    565     bt_semaphore_destroy(lock_fd);
    566 #endif /* WIFI_BT_STATUS_SYNC */
    567 
    568 done:
    569     if (fd >= 0)
    570         close(fd);
    571     return 0;
    572 }
    573 
    574 static inline void soc_init(int soc_type)
    575 {
    576     switch (soc_type)
    577     {
    578     case BT_SOC_CHEROKEE:
    579     case BT_SOC_ROME:
    580     case BT_SOC_AR3K:
    581         ALOGI("bt-vendor : Initializing UART transport layer");
    582         userial_vendor_init();
    583         break;
    584     case BT_SOC_DEFAULT:
    585         break;
    586     default:
    587         ALOGE("Unknown soc yype: %d", soc_type);
    588         break;
    589     }
    590 }
    591 
    592 /* Copy BD Address as little-endian byte order */
    593 static inline void le2bd(unsigned char *src, unsigned char *dst)
    594 {
    595     int i;
    596     for (i = 0; i < 6; i++)
    597         dst[i] = src[5-i];
    598 }
    599 
    600 static inline void print_bdaddr(unsigned char *addr)
    601 {
    602     ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1],
    603             addr[2], addr[3], addr[4], addr[5]);
    604 }
    605 
    606 /*****************************************************************************
    607 **
    608 **   BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
    609 **
    610 *****************************************************************************/
    611 
    612 static int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr)
    613 {
    614     char prop[PROPERTY_VALUE_MAX] = {0};
    615     struct bt_qcom_struct *temp = NULL;
    616     int ret = BT_STATUS_SUCCESS, i;
    617 
    618     ALOGI("++%s", __FUNCTION__);
    619 
    620     if (!cb || !bdaddr) {
    621         ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr);
    622         ret = -BT_STATUS_INVAL;
    623         goto out;
    624     }
    625 
    626     temp = (struct bt_qcom_struct *) malloc(sizeof(*q));
    627     if (!temp) {
    628         ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno);
    629         ret = -BT_STATUS_NOMEM;
    630         goto out;
    631     }
    632     memset(temp, 0, sizeof(*temp));
    633 
    634     temp->rfkill_id = -1;
    635     temp->enable_extldo = FALSE;
    636     temp->cb = cb;
    637     temp->ant_fd = -1;
    638     temp->soc_type = get_bt_soc_type();
    639     soc_init(temp->soc_type);
    640 
    641     le2bd(bdaddr, temp->bdaddr);
    642     print_bdaddr(temp->bdaddr);
    643     snprintf(prop, sizeof(prop), "%02x:%02x:%02x:%02x:%02x:%02x",
    644              temp->bdaddr[0], temp->bdaddr[1], temp->bdaddr[2],
    645              temp->bdaddr[3], temp->bdaddr[4], temp->bdaddr[5]);
    646     ret = property_set("wc_transport.stack_bdaddr", prop);
    647     if (ret < 0) {
    648         ALOGE("Failed to set wc_transport.stack_bdaddr prop, ret = %d", ret);
    649         ret = -BT_STATUS_PROP_FAILURE;
    650         goto out;
    651     }
    652 
    653 /* TODO: Move these fields inside bt_qcom context */
    654 #ifdef WIFI_BT_STATUS_SYNC
    655     isInit = 1;
    656 #endif /* WIFI_BT_STATUS_SYNC */
    657 
    658     /* Everything successful */
    659     q = temp;
    660     return ret;
    661 
    662 out:
    663     if (temp)
    664         free(temp);
    665     ALOGI("--%s ret %d", __FUNCTION__, ret);
    666     return ret;
    667 }
    668 
    669 #ifdef READ_BT_ADDR_FROM_PROP
    670 static bool validate_tok(char* bdaddr_tok) {
    671     int i = 0;
    672     bool ret;
    673 
    674     if (strlen(bdaddr_tok) != 2) {
    675         ret = FALSE;
    676         ALOGE("Invalid token length");
    677     } else {
    678         ret = TRUE;
    679         for (i=0; i<2; i++) {
    680             if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') ||
    681                 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') ||
    682                 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) {
    683                 ret = TRUE;
    684                 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i);
    685              } else {
    686                 ret = FALSE;
    687                 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i);
    688                 break;
    689              }
    690         }
    691     }
    692     return ret;
    693 }
    694 #endif /*READ_BT_ADDR_FROM_PROP*/
    695 
    696 int connect_to_local_socket(char* name) {
    697        socklen_t len; int sk = -1;
    698 
    699        ALOGE("%s: ACCEPT ", __func__);
    700        sk  = socket(AF_LOCAL, SOCK_STREAM, 0);
    701        if (sk < 0) {
    702            ALOGE("Socket creation failure");
    703            return -1;
    704        }
    705 
    706         if(socket_local_client_connect(sk, name,
    707             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
    708         {
    709              ALOGE("failed to connect (%s)", strerror(errno));
    710              close(sk);
    711              sk = -1;
    712         } else {
    713                 ALOGE("%s: Connection succeeded\n", __func__);
    714         }
    715         return sk;
    716 }
    717 
    718 bool is_soc_initialized() {
    719     bool init = false;
    720     char init_value[PROPERTY_VALUE_MAX];
    721     int ret;
    722 
    723     ALOGI("bt-vendor : is_soc_initialized");
    724 
    725     ret = property_get(SOC_INIT_PROPERTY, init_value, NULL);
    726     if (ret != 0) {
    727         ALOGI("%s set to %s\n", SOC_INIT_PROPERTY, init_value);
    728         if (!strncasecmp(init_value, "1", sizeof("1"))) {
    729             init = true;
    730         }
    731     }
    732     else {
    733         ALOGE("%s: Failed to get %s", __FUNCTION__, SOC_INIT_PROPERTY);
    734     }
    735 
    736     return init;
    737 }
    738 
    739 /* flavor of op without locks */
    740 static int __op(bt_vendor_opcode_t opcode, void *param)
    741 {
    742     int retval = BT_STATUS_SUCCESS;
    743     int nCnt = 0;
    744     int nState = -1;
    745     bool is_ant_req = false;
    746     bool is_fm_req = false;
    747     char wipower_status[PROPERTY_VALUE_MAX];
    748     char emb_wp_mode[PROPERTY_VALUE_MAX];
    749     char bt_version[PROPERTY_VALUE_MAX];
    750     char lpm_config[PROPERTY_VALUE_MAX];
    751     bool ignore_boot_prop = TRUE;
    752 #ifdef READ_BT_ADDR_FROM_PROP
    753     int i = 0;
    754     static char bd_addr[PROPERTY_VALUE_MAX];
    755     uint8_t local_bd_addr_from_prop[6];
    756     char* tok;
    757 #endif
    758     bool skip_init = true;
    759     int  opcode_init = opcode;
    760     ALOGV("++%s opcode %d", __FUNCTION__, opcode);
    761 
    762     switch(opcode_init)
    763     {
    764 #ifdef FM_OVER_UART
    765         case FM_VND_OP_POWER_CTRL:
    766             {
    767               is_fm_req = true;
    768               if (is_soc_initialized()) {
    769                   // add any FM specific actions  if needed in future
    770                   break;
    771               }
    772             }
    773 #endif
    774         case BT_VND_OP_POWER_CTRL:
    775             {
    776                 if (!param) {
    777                     ALOGE("opcode = %d: param is null", opcode_init);
    778                     break;
    779                 }
    780                 nState = *(int *) param;
    781                 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s",
    782                         (nState == BT_VND_PWR_ON)? "On" : "Off" );
    783 
    784                 switch(q->soc_type)
    785                 {
    786                     case BT_SOC_DEFAULT:
    787                         if (readTrpState())
    788                         {
    789                            ALOGI("bt-vendor : resetting BT status");
    790                            hw_config(BT_VND_PWR_OFF);
    791                         }
    792                         retval = hw_config(nState);
    793                         if(nState == BT_VND_PWR_ON
    794                            && retval == 0
    795                            && is_hw_ready() == TRUE){
    796                             retval = 0;
    797                         }
    798                         else {
    799                             retval = -1;
    800                         }
    801                         break;
    802                     case BT_SOC_ROME:
    803                     case BT_SOC_AR3K:
    804                     case BT_SOC_CHEROKEE:
    805                         if (q->soc_type == BT_SOC_ROME)
    806                         {
    807                             if (nState == BT_VND_PWR_ON)
    808                             {
    809                                 /* Always power BT off before power on. */
    810                                 ALOGI("bt-vendor: always power off before power on");
    811                                 bt_powerup(BT_VND_PWR_OFF);
    812                             }
    813                         }
    814 
    815                         /* BT Chipset Power Control through Device Tree Node */
    816                         retval = bt_powerup(nState);
    817                     default:
    818                         break;
    819                 }
    820             }
    821             break;
    822 
    823         case BT_VND_OP_FW_CFG: {
    824                 /* call hciattach to initalize the stack */
    825                 if (q->soc_type == BT_SOC_ROME) {
    826                     if (is_soc_initialized()) {
    827                         ALOGI("Bluetooth FW and transport layer are initialized");
    828                         q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    829                     } else {
    830                         ALOGE("bt_vendor_cbacks is null or SoC not initialized");
    831                         ALOGE("Error : hci, smd initialization Error");
    832                         retval = -1;
    833                     }
    834                 } else {
    835                     ALOGI("Bluetooth FW and transport layer are initialized");
    836                     q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
    837                 }
    838         }
    839             break;
    840 
    841         case BT_VND_OP_SCO_CFG:
    842             q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
    843             break;
    844 #ifdef ENABLE_ANT
    845         case BT_VND_OP_ANT_USERIAL_OPEN:
    846                 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN");
    847                 is_ant_req = true;
    848                 goto userial_open;
    849 #endif
    850 #ifdef FM_OVER_UART
    851         case BT_VND_OP_FM_USERIAL_OPEN:
    852                 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_OPEN");
    853                 is_fm_req = true;
    854                 goto userial_open;
    855 #endif
    856 userial_open:
    857         case BT_VND_OP_USERIAL_OPEN:
    858             {
    859                 if (!param) {
    860                     ALOGE("opcode = %d: param is null", opcode_init);
    861                     break;
    862                 }
    863                 int (*fd_array)[] = (int (*)[]) param;
    864                 int idx, fd = -1, fd_filter = -1;
    865                 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
    866                 switch(q->soc_type)
    867                 {
    868                     case BT_SOC_DEFAULT:
    869                         {
    870                             if(bt_hci_init_transport(q->fd) != -1){
    871                                 int (*fd_array)[] = (int (*) []) param;
    872 
    873                                     (*fd_array)[CH_CMD] = q->fd[0];
    874                                     (*fd_array)[CH_EVT] = q->fd[0];
    875                                     (*fd_array)[CH_ACL_OUT] = q->fd[1];
    876                                     (*fd_array)[CH_ACL_IN] = q->fd[1];
    877                             }
    878                             else {
    879                                 retval = -1;
    880                                 break;
    881                             }
    882                             retval = 2;
    883                         }
    884                         break;
    885                     case BT_SOC_AR3K:
    886                         {
    887                             fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
    888                             if (fd != -1) {
    889                                 for (idx=0; idx < CH_MAX; idx++)
    890                                     (*fd_array)[idx] = fd;
    891                                      retval = 1;
    892                             }
    893                             else {
    894                                 retval = -1;
    895                                 break;
    896                             }
    897 
    898                             /* Vendor Specific Process should happened during userial_open process
    899                                 After userial_open, rx read thread is running immediately,
    900                                 so it will affect VS event read process.
    901                             */
    902                             if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0)
    903                                 retval = -1;
    904                         }
    905                         break;
    906                     case BT_SOC_ROME:
    907                         {
    908                             wait_for_patch_download(is_ant_req);
    909                             property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false);
    910                             if (!is_soc_initialized()) {
    911                                 char* dlnd_inprog = is_ant_req ? "ant" : "bt";
    912                                 if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) {
    913                                     ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog);
    914                                 }
    915 
    916                                 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
    917                                 if (fd < 0) {
    918                                     ALOGE("userial_vendor_open returns err");
    919                                     retval = -1;
    920                                     break;
    921                                 }
    922 
    923                                 /* Clock on */
    924                                 userial_clock_operation(fd, USERIAL_OP_CLK_ON);
    925 
    926                                 if(strcmp(emb_wp_mode, "true") == 0) {
    927                                     property_get("ro.bluetooth.wipower", wipower_status, false);
    928                                     if(strcmp(wipower_status, "true") == 0) {
    929                                         check_embedded_mode(fd);
    930                                     } else {
    931                                         ALOGI("Wipower not enabled");
    932                                     }
    933                                 }
    934                                 ALOGV("rome_soc_init is started");
    935                                 property_set("wc_transport.soc_initialized", "0");
    936 #ifdef READ_BT_ADDR_FROM_PROP
    937                                 /*Give priority to read BD address from boot property*/
    938                                 ignore_boot_prop = FALSE;
    939                                 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) {
    940                                     ALOGV("BD address read from Boot property: %s\n", bd_addr);
    941                                     tok =  strtok(bd_addr, ":");
    942                                     while (tok != NULL) {
    943                                         ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16));
    944                                         if (i>=6) {
    945                                             ALOGE("bd property of invalid length");
    946                                             ignore_boot_prop = TRUE;
    947                                             break;
    948                                         }
    949                                         if (i == 6 && !ignore_boot_prop) {
    950                                             ALOGV("Valid BD address read from prop");
    951                                             memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
    952                                             ignore_boot_prop = FALSE;
    953                                         } else {
    954                                             ALOGE("There are not enough tokens in BD addr");
    955                                             ignore_boot_prop = TRUE;
    956                                             break;
    957                                         }
    958                                         local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16);
    959                                         tok = strtok(NULL, ":");
    960                                         i++;
    961                                     }
    962                                     if (i == 6 && !ignore_boot_prop) {
    963                                         ALOGV("Valid BD address read from prop");
    964                                         memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
    965                                         ignore_boot_prop = FALSE;
    966                                     } else {
    967                                         ALOGE("There are not enough tokens in BD addr");
    968                                         ignore_boot_prop = TRUE;
    969                                     }
    970                                 }
    971                                 else {
    972                                      ALOGE("BD address boot property not set");
    973                                      ignore_boot_prop = TRUE;
    974                                 }
    975 #endif //READ_BT_ADDR_FROM_PROP
    976                                     /* Always read BD address from NV file */
    977                                 if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr))
    978                                 {
    979                                    /* Since the BD address is configured in boot time We should not be here */
    980                                    ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
    981                                 }
    982                                 if(rome_soc_init(fd, (char*)q->bdaddr)<0) {
    983                                     retval = -1;
    984                                 } else {
    985                                     ALOGV("rome_soc_init is completed");
    986                                     property_set("wc_transport.soc_initialized", "1");
    987                                     skip_init = false;
    988                                 }
    989                             }
    990                             if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
    991                                 ALOGE("%s: Failed to set property", __FUNCTION__);
    992                             }
    993 
    994                             property_set("wc_transport.clean_up","0");
    995                             if (retval != -1) {
    996 
    997                                 retval = start_hci_filter();
    998                                 if (retval < 0) {
    999                                     ALOGE("%s: WCNSS_FILTER wouldn't have started in time\n", __func__);
   1000                                 } else {
   1001 #ifdef ENABLE_ANT
   1002                                     if (is_ant_req) {
   1003                                         ALOGI("%s: connect to ant channel", __func__);
   1004                                         q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
   1005                                     }
   1006                                     else
   1007 #endif
   1008                                     {
   1009                                         ALOGI("%s: connect to bt channel", __func__);
   1010                                         vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
   1011                                     }
   1012 
   1013                                     if (fd_filter != -1) {
   1014                                         ALOGI("%s: received the socket fd: %d is_ant_req: %d is_fm_req: %d\n",
   1015                                                              __func__, fd_filter, is_ant_req,is_fm_req);
   1016                                         if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req && !is_fm_req) {
   1017                                              if (chipset_ver >= ROME_VER_3_0) {
   1018                                                 /* get rome supported feature request */
   1019                                                 ALOGE("%s: %x08 %0x", __FUNCTION__,chipset_ver, ROME_VER_3_0);
   1020                                                 rome_get_addon_feature_list(fd_filter);
   1021                                             }
   1022                                         }
   1023                                         if (!skip_init) {
   1024                                             /*Skip if already sent*/
   1025                                             enable_controller_log(fd_filter, (is_ant_req || is_fm_req) );
   1026                                             skip_init = true;
   1027                                         }
   1028                                         for (idx=0; idx < CH_MAX; idx++)
   1029                                             (*fd_array)[idx] = fd_filter;
   1030                                             retval = 1;
   1031                                     }
   1032                                     else {
   1033                                         if (is_ant_req)
   1034                                             ALOGE("Unable to connect to ANT Server Socket!!!");
   1035                                         else
   1036                                             ALOGE("Unable to connect to BT Server Socket!!!");
   1037                                         retval = -1;
   1038                                     }
   1039                                 }
   1040                             } else {
   1041                                 if (q->soc_type == BT_SOC_ROME)
   1042                                     ALOGE("Failed to initialize ROME Controller!!!");
   1043                             }
   1044 
   1045                             if (fd >= 0) {
   1046                                 userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
   1047                                  /*Close the UART port*/
   1048                                  close(fd);
   1049                             }
   1050                         }
   1051                         break;
   1052                     case BT_SOC_CHEROKEE:
   1053                         {
   1054                             property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false);
   1055                             retval = start_hci_filter();
   1056                             if (retval < 0) {
   1057                                 ALOGE("WCNSS_FILTER wouldn't have started in time\n");
   1058 
   1059                             } else {
   1060 #ifdef ENABLE_ANT
   1061                                 if (is_ant_req) {
   1062                                     ALOGI("%s: connect to ant channel", __func__);
   1063                                     q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
   1064                                 }
   1065                                 else
   1066 #endif
   1067 #ifdef FM_OVER_UART
   1068                                 if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) {
   1069                                     ALOGI("%s: connect to fm channel", __func__);
   1070                                     q->fm_fd = fd_filter = connect_to_local_socket("fm_sock");
   1071                                 }
   1072                                 else
   1073 #endif
   1074                                 {
   1075                                     ALOGI("%s: connect to bt channel", __func__);
   1076                                     vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
   1077 
   1078                                 }
   1079                                 if (fd_filter != -1) {
   1080                                     ALOGV("%s: received the socket fd: %d \n",
   1081                                                              __func__, fd_filter);
   1082 
   1083                                     for (idx=0; idx < CH_MAX; idx++) {
   1084                                         (*fd_array)[idx] = fd_filter;
   1085                                     }
   1086                                     retval = 1;
   1087                                 }
   1088                                 else {
   1089 #ifdef ENABLE_ANT
   1090                                     if (is_ant_req)
   1091                                         ALOGE("Unable to connect to ANT Server Socket!!!");
   1092                                     else
   1093 #endif
   1094 #ifdef FM_OVER_UART
   1095                                     if (is_fm_req)
   1096                                         ALOGE("Unable to connect to FM Server Socket!!!");
   1097                                     else
   1098 #endif
   1099                                         ALOGE("Unable to connect to BT Server Socket!!!");
   1100                                     retval = -1;
   1101                                 }
   1102                             }
   1103                         }
   1104                         break;
   1105                     default:
   1106                         ALOGE("Unknown soc_type: 0x%x", q->soc_type);
   1107                         break;
   1108                   }
   1109             } break;
   1110 #ifdef ENABLE_ANT
   1111         case BT_VND_OP_ANT_USERIAL_CLOSE:
   1112             {
   1113                 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
   1114                 property_set("wc_transport.clean_up","1");
   1115                 if (q->ant_fd != -1) {
   1116                     ALOGE("closing ant_fd");
   1117                     close(q->ant_fd);
   1118                     q->ant_fd = -1;
   1119                 }
   1120             }
   1121             break;
   1122 #endif
   1123 #ifdef FM_OVER_UART
   1124         case BT_VND_OP_FM_USERIAL_CLOSE:
   1125             {
   1126                 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE");
   1127                 property_set("wc_transport.clean_up","1");
   1128                 if (q->fm_fd != -1) {
   1129                     ALOGE("closing fm_fd");
   1130                     close(q->fm_fd);
   1131                     q->fm_fd = -1;
   1132                 }
   1133                 break;
   1134             }
   1135 #endif
   1136         case BT_VND_OP_USERIAL_CLOSE:
   1137             {
   1138                 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type);
   1139                 switch(q->soc_type)
   1140                 {
   1141                     case BT_SOC_DEFAULT:
   1142                         bt_hci_deinit_transport(q->fd);
   1143                         break;
   1144                     case BT_SOC_ROME:
   1145                     case BT_SOC_AR3K:
   1146                     case BT_SOC_CHEROKEE:
   1147                     {
   1148                         property_set("wc_transport.clean_up","1");
   1149                         userial_vendor_close();
   1150                         break;
   1151                     }
   1152                     default:
   1153                         ALOGE("Unknown soc_type: 0x%x", q->soc_type);
   1154                         break;
   1155                 }
   1156             }
   1157             break;
   1158 
   1159         case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
   1160             {
   1161                 if (!param) {
   1162                     ALOGE("opcode = %d: param is null", opcode_init);
   1163                     break;
   1164                 }
   1165                 uint32_t *timeout_ms = (uint32_t *) param;
   1166                 *timeout_ms = 1000;
   1167             }
   1168 
   1169             break;
   1170 
   1171         case BT_VND_OP_LPM_SET_MODE:
   1172             if (q->soc_type == BT_SOC_AR3K) {
   1173                 if (!param) {
   1174                     ALOGE("opcode = %d: param is null", opcode_init);
   1175                     break;
   1176                 }
   1177                 uint8_t *mode = (uint8_t *) param;
   1178 
   1179                 if (*mode) {
   1180                     lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0);
   1181                 }
   1182                 else {
   1183                     lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
   1184                 }
   1185                 q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
   1186             } else {
   1187                 int lpm_result = BT_VND_OP_RESULT_SUCCESS;
   1188 
   1189                 property_get("persist.service.bdroid.lpmcfg", lpm_config, "all");
   1190                 ALOGI("%s: property_get: persist.service.bdroid.lpmcfg: %s",
   1191                             __func__, lpm_config);
   1192 
   1193                 if (!strcmp(lpm_config, "all")) {
   1194                     // respond with success since we want to hold wake lock through LPM
   1195                     lpm_result = BT_VND_OP_RESULT_SUCCESS;
   1196                 }
   1197                 else {
   1198                     lpm_result = BT_VND_OP_RESULT_FAIL;
   1199                 }
   1200 
   1201                 q->cb->lpm_cb(lpm_result);
   1202             }
   1203             break;
   1204 
   1205         case BT_VND_OP_LPM_WAKE_SET_STATE: {
   1206             switch(q->soc_type) {
   1207             case BT_SOC_CHEROKEE:
   1208             case BT_SOC_ROME: {
   1209                 if (!param) {
   1210                     ALOGE("opcode = %d: param is null", opcode_init);
   1211                     break;
   1212                 }
   1213                 uint8_t *state = (uint8_t *) param;
   1214                 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
   1215                             BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
   1216 
   1217                 if (wake_assert == 0)
   1218                     ALOGV("ASSERT: Waking up BT-Device");
   1219                 else if (wake_assert == 1)
   1220                     ALOGV("DEASSERT: Allowing BT-Device to Sleep");
   1221 
   1222 #ifdef QCOM_BT_SIBS_ENABLE
   1223                 ALOGI("Invoking HCI H4 callback function");
   1224                 q->cb->lpm_set_state_cb(wake_assert);
   1225 #endif
   1226             }
   1227             break;
   1228             case BT_SOC_AR3K: {
   1229                 if (!param) {
   1230                     ALOGE("opcode = %d: param is null", opcode_init);
   1231                     break;
   1232                 }
   1233                 uint8_t *state = (uint8_t *) param;
   1234                 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
   1235                                                 UPIO_ASSERT : UPIO_DEASSERT;
   1236                 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
   1237             }
   1238             case BT_SOC_DEFAULT:
   1239                 break;
   1240             default:
   1241                 ALOGE("Unknown soc_type: 0x%x", q->soc_type);
   1242                 break;
   1243             }
   1244         }
   1245             break;
   1246         case BT_VND_OP_EPILOG: {
   1247 #if (HW_NEED_END_WITH_HCI_RESET == FALSE)
   1248             q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
   1249 #else
   1250                 switch(q->soc_type)
   1251                 {
   1252                   case BT_SOC_CHEROKEE:
   1253                   case BT_SOC_ROME:
   1254                        {
   1255                            char value[PROPERTY_VALUE_MAX] = {'\0'};
   1256                            property_get("wc_transport.hci_filter_status", value, "0");
   1257                            if(is_soc_initialized()&& (strcmp(value,"1") == 0))
   1258                            {
   1259                               __hw_epilog_process();
   1260                            }
   1261                            else
   1262                            {
   1263                                 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
   1264                            }
   1265                        }
   1266                        break;
   1267                   default:
   1268                        __hw_epilog_process();
   1269                        break;
   1270                 }
   1271 #endif
   1272             }
   1273             break;
   1274         case BT_VND_OP_GET_LINESPEED:
   1275             {
   1276                 retval = -1;
   1277                 if(!is_soc_initialized()) {
   1278                      ALOGE("BT_VND_OP_GET_LINESPEED: error"
   1279                          " - transport driver not initialized!");
   1280                      break;
   1281                 }
   1282 
   1283                 switch(q->soc_type)
   1284                 {
   1285                     case BT_SOC_CHEROKEE:
   1286                             retval = 3200000;
   1287                         break;
   1288                     case BT_SOC_ROME:
   1289                             retval = 3000000;
   1290                         break;
   1291                     default:
   1292                         retval = userial_vendor_get_baud();
   1293                         break;
   1294                  }
   1295                 break;
   1296             }
   1297     }
   1298 
   1299 out:
   1300     ALOGV("--%s", __FUNCTION__);
   1301     return retval;
   1302 }
   1303 
   1304 static int op(bt_vendor_opcode_t opcode, void *param)
   1305 {
   1306     int ret;
   1307     ALOGV("++%s", __FUNCTION__);
   1308 #ifdef BT_THREADLOCK_SAFE
   1309     pthread_mutex_lock(&q_lock);
   1310 #endif
   1311     if (!q) {
   1312         ALOGE("op called with NULL context");
   1313         ret = -BT_STATUS_INVAL;
   1314         goto out;
   1315     }
   1316     ret = __op(opcode, param);
   1317 out:
   1318 #ifdef BT_THREADLOCK_SAFE
   1319     pthread_mutex_unlock(&q_lock);
   1320 #endif
   1321     ALOGV("--%s ret = 0x%x", __FUNCTION__, ret);
   1322     return ret;
   1323 }
   1324 
   1325 static void ssr_cleanup(int reason)
   1326 {
   1327     int pwr_state = BT_VND_PWR_OFF;
   1328     int ret;
   1329     unsigned char trig_ssr = 0xEE;
   1330 
   1331     ALOGI("++%s", __FUNCTION__);
   1332 
   1333     pthread_mutex_lock(&q_lock);
   1334     if (!q) {
   1335         ALOGE("ssr_cleanup called with NULL context");
   1336         goto out;
   1337     }
   1338     if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
   1339         ALOGE("Failed to set property");
   1340     }
   1341 
   1342     if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) {
   1343 #ifdef ENABLE_ANT
   1344         /*Indicate to filter by sending special byte */
   1345         if (reason == CMD_TIMEOUT) {
   1346             trig_ssr = 0xEE;
   1347             ret = write (vnd_userial.fd, &trig_ssr, 1);
   1348             ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s",
   1349                         ret, strerror(errno));
   1350 
   1351             if (is_debug_force_special_bytes()) {
   1352                 /*
   1353                  * Then we should send special byte to crash SOC in
   1354                  * WCNSS_Filter, so we do not need to power off UART here.
   1355                  */
   1356                 goto out;
   1357             }
   1358         }
   1359 
   1360         /* Close both ANT channel */
   1361         __op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
   1362 #endif
   1363         /* Close both BT channel */
   1364         __op(BT_VND_OP_USERIAL_CLOSE, NULL);
   1365 
   1366 #ifdef FM_OVER_UART
   1367         __op(BT_VND_OP_FM_USERIAL_CLOSE, NULL);
   1368 #endif
   1369         /*CTRL OFF twice to make sure hw
   1370          * turns off*/
   1371 #ifdef ENABLE_ANT
   1372         __op(BT_VND_OP_POWER_CTRL, &pwr_state);
   1373 #endif
   1374     }
   1375     /*Generally switching of chip should be enough*/
   1376     __op(BT_VND_OP_POWER_CTRL, &pwr_state);
   1377 
   1378 out:
   1379     pthread_mutex_unlock(&q_lock);
   1380     ALOGI("--%s", __FUNCTION__);
   1381 }
   1382 
   1383 /** Closes the interface */
   1384 static void cleanup(void)
   1385 {
   1386     ALOGI("cleanup");
   1387 
   1388     pthread_mutex_lock(&q_lock);
   1389     q->cb = NULL;
   1390     free(q);
   1391     q = NULL;
   1392     pthread_mutex_unlock(&q_lock);
   1393 
   1394 #ifdef WIFI_BT_STATUS_SYNC
   1395     isInit = 0;
   1396 #endif /* WIFI_BT_STATUS_SYNC */
   1397 }
   1398 
   1399 /* Check for one of the cients ANT/BT patch download is already in
   1400 ** progress if yes wait till complete
   1401 */
   1402 void wait_for_patch_download(bool is_ant_req) {
   1403     ALOGV("%s:", __FUNCTION__);
   1404     char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
   1405     while (1) {
   1406         property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
   1407 
   1408         if(is_ant_req && !(strcmp(inProgress,"bt"))) {
   1409            //ANT request, wait for BT to finish
   1410            usleep(50000);
   1411         }
   1412         else if(!is_ant_req && !(strcmp(inProgress,"ant"))) {
   1413           //BT request, wait for ANT to finish
   1414            usleep(50000);
   1415         }
   1416         else {
   1417            ALOGI("%s: patch download completed", __FUNCTION__);
   1418            break;
   1419         }
   1420     }
   1421 }
   1422 
   1423 bool is_download_progress () {
   1424     char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
   1425     bool retval = false;
   1426 
   1427     ALOGV("%s:", __FUNCTION__);
   1428 
   1429     if ((q->soc_type = get_bt_soc_type()) < 0) {
   1430         ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
   1431         return -1;
   1432     }
   1433 
   1434     switch(q->soc_type)
   1435     {
   1436         case BT_SOC_ROME:
   1437             ALOGI("%s: ROME case", __func__);
   1438             property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
   1439             if(strcmp(inProgress,"null") == 0) {
   1440                 retval = false;
   1441             } else {
   1442                  retval = true;
   1443             }
   1444             break;
   1445         case BT_SOC_CHEROKEE:
   1446             ALOGI("%s: CHEROKEE case", __func__);
   1447             break;
   1448         case BT_SOC_DEFAULT:
   1449             break;
   1450         default:
   1451             ALOGE("Unknown btSocType: 0x%x", q->soc_type);
   1452             break;
   1453     }
   1454     return retval;
   1455 }
   1456 
   1457 static bool is_debug_force_special_bytes() {
   1458     int ret = 0;
   1459     char value[PROPERTY_VALUE_MAX] = {'\0'};
   1460     bool enabled = false;
   1461 #ifdef ENABLE_DBG_FLAGS
   1462     enabled = true;
   1463 #endif
   1464 
   1465     ret = property_get("wc_transport.force_special_byte", value, NULL);
   1466 
   1467     if (ret) {
   1468         enabled = (strcmp(value, "false") ==0) ? false : true;
   1469         ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ",
   1470             __func__, value, enabled);
   1471     }
   1472 
   1473     return enabled;
   1474 }
   1475 
   1476 // Entry point of DLib
   1477 /* Remove 'ssr_cleanup' because it's not defined in 'bt_vendor_interface_t'. */
   1478 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
   1479     sizeof(bt_vendor_interface_t),
   1480     init,
   1481     op,
   1482     cleanup
   1483 };
   1484