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