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