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