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 
59 static void wait_for_patch_download(bool is_ant_req);
60 static bool is_debug_force_special_bytes(void);
61 int connect_to_local_socket(char* name);
62 /******************************************************************************
63 **  Externs
64 ******************************************************************************/
65 extern int hw_config(int nState);
66 extern int is_hw_ready();
67 extern int chipset_ver;
68 
69 /******************************************************************************
70 **  Variables
71 ******************************************************************************/
72 struct bt_qcom_struct q;
73 pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER;
74 
75 int userial_clock_operation(int fd, int cmd);
76 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
77 int userial_vendor_get_baud(void);
78 int readTrpState();
79 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
80 bool is_download_progress();
81 
82 static 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)
89 void __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 
98 static const char WIFI_PROP_NAME[]    = "wlan.driver.status";
99 static const char SERVICE_PROP_NAME[]    = "bluetooth.hsic_ctrl";
100 static const char BT_STATUS_NAME[]    = "bluetooth.enabled";
101 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
102 
103 #define WIFI_BT_STATUS_LOCK    "/data/connectivity/wifi_bt_lock"
104 int isInit=0;
105 #endif /* WIFI_BT_STATUS_SYNC */
106 bool is_soc_initialized(void);
107 
108 /******************************************************************************
109 **  Local type definitions
110 ******************************************************************************/
111 
112 /******************************************************************************
113 **  Functions
114 ******************************************************************************/
115 #ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_create(void)116 int 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 
bt_semaphore_get(int fd)128 int 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 
bt_semaphore_release(int fd)144 int 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 
bt_semaphore_destroy(int fd)160 int bt_semaphore_destroy(int fd)
161 {
162     if (fd < 0)
163         return -1;
164 
165     return close (fd);
166 }
167 
bt_wait_for_service_done(void)168 int 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 */
get_bt_soc_type()192 static 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 
can_perform_action(char action)227 bool 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 
stop_hci_filter()281 void 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 
start_hci_filter()329 int 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  */
bt_powerup(int en)370 static 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 
552 done:
553     if (fd >= 0)
554         close(fd);
555     return 0;
556 }
557 
soc_init(int soc_type)558 static 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 */
le2bd(unsigned char * src,unsigned char * dst)577 static 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 
print_bdaddr(unsigned char * addr)584 static 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 
init(const bt_vendor_callbacks_t * cb,unsigned char * bdaddr)596 static 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 
636 out:
637     ALOGI("--%s ret %d", __FUNCTION__, ret);
638     return ret;
639 }
640 
641 #ifdef READ_BT_ADDR_FROM_PROP
validate_tok(char * bdaddr_tok)642 static 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 
connect_to_local_socket(char * name)668 int 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 
is_soc_initialized()690 bool 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 */
op(bt_vendor_opcode_t opcode,void * param)712 static 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
820 userial_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 
1275 out:
1276     ALOGV("--%s", __FUNCTION__);
1277     return retval;
1278 }
1279 
ssr_cleanup(int reason)1280 static 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 
1331 out:
1332     ALOGI("--%s", __FUNCTION__);
1333 }
1334 
1335 /** Closes the interface */
cleanup(void)1336 static 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 */
wait_for_patch_download(bool is_ant_req)1352 void 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 
is_download_progress()1373 bool 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 
is_debug_force_special_bytes()1407 static 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
1427 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1428     sizeof(bt_vendor_interface_t),
1429     init,
1430     op,
1431     cleanup
1432 };
1433