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