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