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
55static void wait_for_patch_download(bool is_ant_req);
56static bool is_debug_force_special_bytes(void);
57int connect_to_local_socket(char* name);
58/******************************************************************************
59**  Externs
60******************************************************************************/
61extern int hw_config(int nState);
62extern int is_hw_ready();
63extern int chipset_ver;
64
65/******************************************************************************
66**  Variables
67******************************************************************************/
68struct bt_qcom_struct *q = NULL;
69pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER;
70
71int userial_clock_operation(int fd, int cmd);
72int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
73int userial_vendor_get_baud(void);
74int readTrpState();
75void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
76bool is_download_progress();
77
78static 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)
85void __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
94static const char WIFI_PROP_NAME[]    = "wlan.driver.status";
95static const char SERVICE_PROP_NAME[]    = "bluetooth.hsic_ctrl";
96static const char BT_STATUS_NAME[]    = "bluetooth.enabled";
97static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
98
99#define WIFI_BT_STATUS_LOCK    "/data/connectivity/wifi_bt_lock"
100int isInit=0;
101#endif /* WIFI_BT_STATUS_SYNC */
102bool is_soc_initialized(void);
103
104/******************************************************************************
105**  Local type definitions
106******************************************************************************/
107
108/******************************************************************************
109**  Functions
110******************************************************************************/
111#ifdef WIFI_BT_STATUS_SYNC
112int 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
124int 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
140int 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
156int bt_semaphore_destroy(int fd)
157{
158    if (fd < 0)
159        return -1;
160
161    return close (fd);
162}
163
164int 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 */
188static 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
223bool 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
277void 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
339int 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 */
380static 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
562done:
563    if (fd >= 0)
564        close(fd);
565    return 0;
566}
567
568static 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 */
587static 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
594static 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
606static 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
656out:
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
664static 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
690int 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
712bool 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 */
734static 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
840userial_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
1289out:
1290    ALOGV("--%s", __FUNCTION__);
1291    return retval;
1292}
1293
1294static 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
1350out:
1351    pthread_mutex_unlock(&q_lock);
1352    ALOGI("--%s", __FUNCTION__);
1353}
1354
1355/** Closes the interface */
1356static 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*/
1374void 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
1395bool 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
1429static 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
1449const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1450    sizeof(bt_vendor_interface_t),
1451    init,
1452    op,
1453    cleanup
1454};
1455