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