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