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