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 #define LOG_TAG "bt_vendor"
27 #define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr"
28
29 #include <utils/Log.h>
30 #include <cutils/properties.h>
31 #include <fcntl.h>
32 #include <termios.h>
33 #include "bt_vendor_qcom.h"
34 #include "hci_uart.h"
35 #include "hci_smd.h"
36 #include <sys/ioctl.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 30
45
46 #define STOP_WCNSS_FILTER 0xDD
47 #define STOP_WAIT_TIMEOUT 1000
48
49 #define SOC_INIT_PROPERTY "wc_transport.soc_initialized"
50
51 #define BT_VND_FILTER_START "wc_transport.start_hci"
52
53 #define CMD_TIMEOUT 0x22
54
55 static void wait_for_patch_download(bool is_ant_req);
56 static bool is_debug_force_special_bytes(void);
57 int connect_to_local_socket(char* name);
58 /******************************************************************************
59 ** Externs
60 ******************************************************************************/
61 extern int hw_config(int nState);
62 extern int is_hw_ready();
63 extern int chipset_ver;
64
65 /******************************************************************************
66 ** Variables
67 ******************************************************************************/
68 struct bt_qcom_struct *q = NULL;
69 pthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER;
70
71 int userial_clock_operation(int fd, int cmd);
72 int ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti);
73 int userial_vendor_get_baud(void);
74 int readTrpState();
75 void lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity);
76 bool is_download_progress();
77
78 static const tUSERIAL_CFG userial_init_cfg =
79 {
80 (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
81 USERIAL_BAUD_115200
82 };
83
84 #if (HW_NEED_END_WITH_HCI_RESET == TRUE)
85 void __hw_epilog_process(void);
86 #endif
87
88 #ifdef WIFI_BT_STATUS_SYNC
89 #include <string.h>
90 #include <errno.h>
91 #include <dlfcn.h>
92 #include "cutils/properties.h"
93
94 static const char WIFI_PROP_NAME[] = "wlan.driver.status";
95 static const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl";
96 static const char BT_STATUS_NAME[] = "bluetooth.enabled";
97 static const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl";
98
99 #define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock"
100 int isInit=0;
101 #endif /* WIFI_BT_STATUS_SYNC */
102 bool is_soc_initialized(void);
103
104 /******************************************************************************
105 ** Local type definitions
106 ******************************************************************************/
107
108 /******************************************************************************
109 ** Functions
110 ******************************************************************************/
111 #ifdef WIFI_BT_STATUS_SYNC
bt_semaphore_create(void)112 int bt_semaphore_create(void)
113 {
114 int fd;
115
116 fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY);
117
118 if (fd < 0)
119 ALOGE("can't create file\n");
120
121 return fd;
122 }
123
bt_semaphore_get(int fd)124 int bt_semaphore_get(int fd)
125 {
126 int ret;
127
128 if (fd < 0)
129 return -1;
130
131 ret = flock(fd, LOCK_EX);
132 if (ret != 0) {
133 ALOGE("can't hold lock: %s\n", strerror(errno));
134 return -1;
135 }
136
137 return ret;
138 }
139
bt_semaphore_release(int fd)140 int bt_semaphore_release(int fd)
141 {
142 int ret;
143
144 if (fd < 0)
145 return -1;
146
147 ret = flock(fd, LOCK_UN);
148 if (ret != 0) {
149 ALOGE("can't release lock: %s\n", strerror(errno));
150 return -1;
151 }
152
153 return ret;
154 }
155
bt_semaphore_destroy(int fd)156 int bt_semaphore_destroy(int fd)
157 {
158 if (fd < 0)
159 return -1;
160
161 return close (fd);
162 }
163
bt_wait_for_service_done(void)164 int bt_wait_for_service_done(void)
165 {
166 char service_status[PROPERTY_VALUE_MAX];
167 int count = 30;
168
169 ALOGE("%s: check\n", __func__);
170
171 /* wait for service done */
172 while (count-- > 0) {
173 property_get(WIFI_SERVICE_PROP, service_status, NULL);
174
175 if (strcmp(service_status, "") != 0) {
176 usleep(200000);
177 } else {
178 break;
179 }
180 }
181
182 return 0;
183 }
184
185 #endif /* WIFI_BT_STATUS_SYNC */
186
187 /** Get Bluetooth SoC type from system setting */
get_bt_soc_type()188 static int get_bt_soc_type()
189 {
190 int ret = 0;
191 char bt_soc_type[PROPERTY_VALUE_MAX];
192
193 ALOGI("bt-vendor : get_bt_soc_type");
194
195 ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL);
196 if (ret != 0) {
197 ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type);
198 if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) {
199 return BT_SOC_ROME;
200 }
201 else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) {
202 return BT_SOC_CHEROKEE;
203 }
204 else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) {
205 return BT_SOC_AR3K;
206 }
207 else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) {
208 return BT_SOC_CHEROKEE;
209 }
210 else {
211 ALOGI("qcom.bluetooth.soc not set, so using default.\n");
212 return BT_SOC_DEFAULT;
213 }
214 }
215 else {
216 ALOGE("%s: Failed to get soc type", __FUNCTION__);
217 ret = BT_SOC_DEFAULT;
218 }
219
220 return ret;
221 }
222
can_perform_action(char action)223 bool can_perform_action(char action) {
224 bool can_perform = false;
225 char ref_count[PROPERTY_VALUE_MAX];
226 char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
227 int value, ret;
228
229 property_get("wc_transport.ref_count", ref_count, "0");
230
231 value = atoi(ref_count);
232 ALOGV("%s: ref_count: %s\n",__func__, ref_count);
233
234 if(action == '1') {
235 ALOGV("%s: on : value is: %d", __func__, value);
236 if(value == 1)
237 {
238 if ((is_soc_initialized() == true)
239 || is_download_progress() || get_bt_soc_type() == BT_SOC_CHEROKEE)
240 {
241 value++;
242 ALOGV("%s: on : value is incremented to : %d", __func__, value);
243 }
244 }
245 else
246 {
247 value++;
248 }
249
250 if (value == 1)
251 can_perform = true;
252 else if (value > 3)
253 return false;
254 }
255 else {
256 ALOGV("%s: off : value is: %d", __func__, value);
257 if (--value <= 0) {
258 ALOGE("%s: BT turn off twice before BT On(ref_count=%d)\n",
259 __func__, value);
260 value = 0;
261 can_perform = true;
262 }
263 }
264
265 snprintf(ref_count, 3, "%d", value);
266 ALOGV("%s: updated ref_count is: %s", __func__, ref_count);
267
268 ret = property_set("wc_transport.ref_count", ref_count);
269 if (ret < 0) {
270 ALOGE("%s: Error while updating property: %d\n", __func__, ret);
271 return false;
272 }
273 ALOGV("%s returning %d", __func__, can_perform);
274 return can_perform;
275 }
276
stop_hci_filter()277 void stop_hci_filter() {
278 char value[PROPERTY_VALUE_MAX] = {'\0'};
279 int retval, filter_ctrl, i;
280 char stop_val = STOP_WCNSS_FILTER;
281 int soc_type = BT_SOC_DEFAULT;
282
283 ALOGV("%s: Entry ", __func__);
284
285 if ((soc_type = get_bt_soc_type()) == BT_SOC_CHEROKEE) {
286 property_get("wc_transport.hci_filter_status", value, "0");
287 if (strcmp(value, "0") == 0) {
288 ALOGI("%s: hci_filter has been stopped already", __func__);
289 }
290 else {
291 filter_ctrl = connect_to_local_socket("wcnssfilter_ctrl");
292 if (filter_ctrl < 0) {
293 ALOGI("%s: Error while connecting to CTRL_SOCK, filter should stopped: %d",
294 __func__, filter_ctrl);
295 }
296 else {
297 retval = write(filter_ctrl, &stop_val, 1);
298 if (retval != 1) {
299 ALOGI("%s: problem writing to CTRL_SOCK, ignore: %d", __func__, retval);
300 //Ignore and fallback
301 }
302
303 close(filter_ctrl);
304 }
305 }
306
307 /* Ensure Filter is closed by checking the status before
308 RFKILL 0 operation. this should ideally comeout very
309 quick */
310 for(i=0; i<500; i++) {
311 property_get(BT_VND_FILTER_START, value, "false");
312 if (strcmp(value, "false") == 0) {
313 ALOGI("%s: WCNSS_FILTER stopped", __func__);
314 usleep(STOP_WAIT_TIMEOUT * 10);
315 break;
316 } else {
317 /*sleep of 1ms, This should give enough time for FILTER to
318 exit with all necessary cleanup*/
319 usleep(STOP_WAIT_TIMEOUT);
320 }
321 }
322
323 /*Never use SIGKILL to stop the filter*/
324 /* Filter will be stopped by below two conditions
325 - by Itself, When it realizes there are no CONNECTED clients
326 - Or through STOP_WCNSS_FILTER byte on Control socket
327 both of these ensure clean shutdown of chip
328 */
329 //property_set(BT_VND_FILTER_START, "false");
330 } else if (soc_type == BT_SOC_ROME) {
331 property_set(BT_VND_FILTER_START, "false");
332 } else {
333 ALOGI("%s: Unknown soc type %d, Unexpected!", __func__, soc_type);
334 }
335
336 ALOGV("%s: Exit ", __func__);
337 }
338
start_hci_filter()339 int start_hci_filter() {
340 ALOGV("%s: Entry ", __func__);
341 int i, init_success = -1;
342 char value[PROPERTY_VALUE_MAX] = {'\0'};
343
344 property_get(BT_VND_FILTER_START, value, false);
345
346 if (strcmp(value, "true") == 0) {
347 ALOGI("%s: hci_filter has been started already", __func__);
348 //Filter should have been started OR in the process of initializing
349 //Make sure of hci_filter_status and return the state based on it
350 } else {
351
352 property_set("wc_transport.hci_filter_status", "0");
353 property_set(BT_VND_FILTER_START, "true");
354 ALOGV("%s: %s set to true ", __func__, BT_VND_FILTER_START );
355 }
356
357 /*If there are back to back ON requests from different clients,
358 All client should come and stuck in this while loop till FILTER
359 comesup and ready to accept the connections */
360 //sched_yield();
361 for(i=0; i<45; i++) {
362 property_get("wc_transport.hci_filter_status", value, "0");
363 if (strcmp(value, "1") == 0) {
364 init_success = 1;
365 break;
366 } else {
367 usleep(WAIT_TIMEOUT);
368 }
369 }
370 ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i);
371
372 ALOGV("%s: Exit ", __func__);
373 return init_success;
374 }
375
376 /*
377 * Bluetooth Controller power up or shutdown, this function is called with
378 * q_lock held and q is non-NULL
379 */
bt_powerup(int en)380 static int bt_powerup(int en )
381 {
382 char rfkill_type[64], *enable_ldo_path = NULL;
383 char type[16], enable_ldo[6];
384 int fd = 0, size, i, ret, fd_ldo, fd_btpower;
385
386 char disable[PROPERTY_VALUE_MAX];
387 char state;
388 char on = (en)?'1':'0';
389
390 #ifdef WIFI_BT_STATUS_SYNC
391 char wifi_status[PROPERTY_VALUE_MAX];
392 int lock_fd;
393 #endif /*WIFI_BT_STATUS_SYNC*/
394
395 ALOGI("bt_powerup: %c", on);
396
397 /* Check if rfkill has been disabled */
398 ret = property_get("ro.rfkilldisabled", disable, "0");
399 if (!ret ){
400 ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret);
401 return -1;
402 }
403 /* In case rfkill disabled, then no control power*/
404 if (strcmp(disable, "1") == 0) {
405 ALOGI("ro.rfkilldisabled : %s", disable);
406 return -1;
407 }
408
409 #ifdef WIFI_BT_STATUS_SYNC
410 lock_fd = bt_semaphore_create();
411 bt_semaphore_get(lock_fd);
412 bt_wait_for_service_done();
413 #endif
414
415 /* Assign rfkill_id and find bluetooth rfkill state path*/
416 for(i = 0; (q->rfkill_id == -1) && (q->rfkill_state == NULL); i++)
417 {
418 snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i);
419 if ((fd = open(rfkill_type, O_RDONLY)) < 0)
420 {
421 ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno);
422
423 #ifdef WIFI_BT_STATUS_SYNC
424 bt_semaphore_release(lock_fd);
425 bt_semaphore_destroy(lock_fd);
426 #endif
427 return -1;
428 }
429
430 size = read(fd, &type, sizeof(type));
431 close(fd);
432
433 if ((size >= 9) && !memcmp(type, "bluetooth", 9))
434 {
435 asprintf(&q->rfkill_state, "/sys/class/rfkill/rfkill%d/state", q->rfkill_id = i);
436 break;
437 }
438 }
439
440 /* Get rfkill State to control */
441 if (q->rfkill_state != NULL)
442 {
443 if ((fd = open(q->rfkill_state, O_RDWR)) < 0)
444 {
445 ALOGE("open(%s) for write failed: %s (%d)", q->rfkill_state, strerror(errno), errno);
446 #ifdef WIFI_BT_STATUS_SYNC
447 bt_semaphore_release(lock_fd);
448 bt_semaphore_destroy(lock_fd);
449 #endif
450
451 return -1;
452 }
453 }
454 if(can_perform_action(on) == false) {
455 ALOGE("%s:can't perform action as it is being used by other clients", __func__);
456 #ifdef WIFI_BT_STATUS_SYNC
457 bt_semaphore_release(lock_fd);
458 bt_semaphore_destroy(lock_fd);
459 #endif
460 goto done;
461 }
462 ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id);
463 if( (ret < 0 ) || (enable_ldo_path == NULL) )
464 {
465 ALOGE("Memory Allocation failure");
466 return -1;
467 }
468 if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) {
469 ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
470 return -1;
471 }
472 size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo));
473 close(fd_ldo);
474 if (size <= 0) {
475 ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno);
476 return -1;
477 }
478 if (!memcmp(enable_ldo, "true", 4)) {
479 ALOGI("External LDO has been configured");
480 ret = property_set("wc_transport.extldo", "enabled");
481 if (ret < 0) {
482 ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__);
483 }
484 q->enable_extldo = TRUE;
485 }
486
487 if(on == '0'){
488 ALOGE("Stopping HCI filter as part of CTRL:OFF");
489 stop_hci_filter();
490 property_set("wc_transport.soc_initialized", "0");
491 }
492
493 if (q->soc_type >= BT_SOC_CHEROKEE && q->soc_type < BT_SOC_RESERVED) {
494 ALOGI("open bt power devnode,send ioctl power op :%d ",en);
495 fd_btpower = open(BT_PWR_CNTRL_DEVICE, O_RDWR, O_NONBLOCK);
496 if (fd_btpower < 0) {
497 ALOGE("\nfailed to open bt device error = (%s)\n",strerror(errno));
498 #ifdef WIFI_BT_STATUS_SYNC
499 bt_semaphore_release(lock_fd);
500 bt_semaphore_destroy(lock_fd);
501 #endif
502 return -1;
503 }
504 ret = ioctl(fd_btpower, BT_CMD_PWR_CTRL, (unsigned long)en);
505 if (ret < 0) {
506 ALOGE(" ioctl failed to power control:%d error =(%s)",ret,strerror(errno));
507 }
508 close(fd_btpower);
509 } else {
510 ALOGI("Write %c to rfkill\n", on);
511 /* Write value to control rfkill */
512 if(fd >= 0) {
513 if ((size = write(fd, &on, 1)) < 0) {
514 ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno);
515 #ifdef WIFI_BT_STATUS_SYNC
516 bt_semaphore_release(lock_fd);
517 bt_semaphore_destroy(lock_fd);
518 #endif
519 return -1;
520 }
521 }
522 }
523 #ifdef WIFI_BT_STATUS_SYNC
524 /* query wifi status */
525 property_get(WIFI_PROP_NAME, wifi_status, "");
526
527 ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit);
528
529 /* If wlan driver is not loaded, and bt is changed from off => on */
530 if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) {
531 if (on == '1') {
532 ALOGI("%s: BT_VND_PWR_ON\n", __func__);
533 if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) {
534 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
535 close(fd);
536 bt_semaphore_release(lock_fd);
537 bt_semaphore_destroy(lock_fd);
538 return -1;
539 }
540 }
541 else if (isInit == 0 && on == '0') {
542 ALOGI("%s: BT_VND_PWR_OFF\n", __func__);
543 if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) {
544 ALOGE("%s Property setting failed", SERVICE_PROP_NAME);
545 close(fd);
546 bt_semaphore_release(lock_fd);
547 bt_semaphore_destroy(lock_fd);
548 return -1;
549 }
550 }
551 }
552
553 if (isInit == 0 && on == '0')
554 property_set(BT_STATUS_NAME, "false");
555 else if (on == '1')
556 property_set(BT_STATUS_NAME, "true");
557
558 bt_semaphore_release(lock_fd);
559 bt_semaphore_destroy(lock_fd);
560 #endif /* WIFI_BT_STATUS_SYNC */
561
562 done:
563 if (fd >= 0)
564 close(fd);
565 return 0;
566 }
567
soc_init(int soc_type)568 static inline void soc_init(int soc_type)
569 {
570 switch (soc_type)
571 {
572 case BT_SOC_CHEROKEE:
573 case BT_SOC_ROME:
574 case BT_SOC_AR3K:
575 ALOGI("bt-vendor : Initializing UART transport layer");
576 userial_vendor_init();
577 break;
578 case BT_SOC_DEFAULT:
579 break;
580 default:
581 ALOGE("Unknown soc yype: %d", soc_type);
582 break;
583 }
584 }
585
586 /* Copy BD Address as little-endian byte order */
le2bd(unsigned char * src,unsigned char * dst)587 static inline void le2bd(unsigned char *src, unsigned char *dst)
588 {
589 int i;
590 for (i = 0; i < 6; i++)
591 dst[i] = src[5-i];
592 }
593
print_bdaddr(unsigned char * addr)594 static inline void print_bdaddr(unsigned char *addr)
595 {
596 ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1],
597 addr[2], addr[3], addr[4], addr[5]);
598 }
599
600 /*****************************************************************************
601 **
602 ** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
603 **
604 *****************************************************************************/
605
init(const bt_vendor_callbacks_t * cb,unsigned char * bdaddr)606 static int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr)
607 {
608 char prop[PROPERTY_VALUE_MAX] = {0};
609 struct bt_qcom_struct *temp = NULL;
610 int ret = BT_STATUS_SUCCESS, i;
611
612 ALOGI("++%s", __FUNCTION__);
613
614 if (!cb || !bdaddr) {
615 ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr);
616 ret = -BT_STATUS_INVAL;
617 goto out;
618 }
619
620 temp = (struct bt_qcom_struct *) malloc(sizeof(*q));
621 if (!temp) {
622 ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno);
623 ret = -BT_STATUS_NOMEM;
624 goto out;
625 }
626 memset(temp, 0, sizeof(*temp));
627
628 temp->rfkill_id = -1;
629 temp->enable_extldo = FALSE;
630 temp->cb = cb;
631 temp->ant_fd = -1;
632 temp->soc_type = get_bt_soc_type();
633 soc_init(temp->soc_type);
634
635 le2bd(bdaddr, temp->bdaddr);
636 print_bdaddr(temp->bdaddr);
637 snprintf(prop, sizeof(prop), "%02x:%02x:%02x:%02x:%02x:%02x",
638 temp->bdaddr[0], temp->bdaddr[1], temp->bdaddr[2],
639 temp->bdaddr[3], temp->bdaddr[4], temp->bdaddr[5]);
640 ret = property_set("wc_transport.stack_bdaddr", prop);
641 if (ret < 0) {
642 ALOGE("Failed to set wc_transport.stack_bdaddr prop, ret = %d", ret);
643 ret = -BT_STATUS_PROP_FAILURE;
644 goto out;
645 }
646
647 /* TODO: Move these fields inside bt_qcom context */
648 #ifdef WIFI_BT_STATUS_SYNC
649 isInit = 1;
650 #endif /* WIFI_BT_STATUS_SYNC */
651
652 /* Everything successful */
653 q = temp;
654 return ret;
655
656 out:
657 if (temp)
658 free(temp);
659 ALOGI("--%s ret %d", __FUNCTION__, ret);
660 return ret;
661 }
662
663 #ifdef READ_BT_ADDR_FROM_PROP
validate_tok(char * bdaddr_tok)664 static bool validate_tok(char* bdaddr_tok) {
665 int i = 0;
666 bool ret;
667
668 if (strlen(bdaddr_tok) != 2) {
669 ret = FALSE;
670 ALOGE("Invalid token length");
671 } else {
672 ret = TRUE;
673 for (i=0; i<2; i++) {
674 if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') ||
675 (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') ||
676 (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) {
677 ret = TRUE;
678 ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i);
679 } else {
680 ret = FALSE;
681 ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i);
682 break;
683 }
684 }
685 }
686 return ret;
687 }
688 #endif /*READ_BT_ADDR_FROM_PROP*/
689
connect_to_local_socket(char * name)690 int connect_to_local_socket(char* name) {
691 socklen_t len; int sk = -1;
692
693 ALOGE("%s: ACCEPT ", __func__);
694 sk = socket(AF_LOCAL, SOCK_STREAM, 0);
695 if (sk < 0) {
696 ALOGE("Socket creation failure");
697 return -1;
698 }
699
700 if(socket_local_client_connect(sk, name,
701 ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
702 {
703 ALOGE("failed to connect (%s)", strerror(errno));
704 close(sk);
705 sk = -1;
706 } else {
707 ALOGE("%s: Connection succeeded\n", __func__);
708 }
709 return sk;
710 }
711
is_soc_initialized()712 bool is_soc_initialized() {
713 bool init = false;
714 char init_value[PROPERTY_VALUE_MAX];
715 int ret;
716
717 ALOGI("bt-vendor : is_soc_initialized");
718
719 ret = property_get(SOC_INIT_PROPERTY, init_value, NULL);
720 if (ret != 0) {
721 ALOGI("%s set to %s\n", SOC_INIT_PROPERTY, init_value);
722 if (!strncasecmp(init_value, "1", sizeof("1"))) {
723 init = true;
724 }
725 }
726 else {
727 ALOGE("%s: Failed to get %s", __FUNCTION__, SOC_INIT_PROPERTY);
728 }
729
730 return init;
731 }
732
733 /* flavor of op without locks */
__op(bt_vendor_opcode_t opcode,void * param)734 static int __op(bt_vendor_opcode_t opcode, void *param)
735 {
736 int retval = BT_STATUS_SUCCESS;
737 int nCnt = 0;
738 int nState = -1;
739 bool is_ant_req = false;
740 bool is_fm_req = false;
741 char wipower_status[PROPERTY_VALUE_MAX];
742 char emb_wp_mode[PROPERTY_VALUE_MAX];
743 char bt_version[PROPERTY_VALUE_MAX];
744 char lpm_config[PROPERTY_VALUE_MAX];
745 bool ignore_boot_prop = TRUE;
746 #ifdef READ_BT_ADDR_FROM_PROP
747 int i = 0;
748 static char bd_addr[PROPERTY_VALUE_MAX];
749 uint8_t local_bd_addr_from_prop[6];
750 char* tok;
751 #endif
752 bool skip_init = true;
753 int opcode_init = opcode;
754 ALOGV("++%s opcode %d", __FUNCTION__, opcode);
755
756 switch(opcode_init)
757 {
758 #ifdef FM_OVER_UART
759 case FM_VND_OP_POWER_CTRL:
760 {
761 is_fm_req = true;
762 if (is_soc_initialized()) {
763 // add any FM specific actions if needed in future
764 break;
765 }
766 }
767 #endif
768 case BT_VND_OP_POWER_CTRL:
769 {
770 if (!param) {
771 ALOGE("opcode = %d: param is null", opcode_init);
772 break;
773 }
774 nState = *(int *) param;
775 ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s",
776 (nState == BT_VND_PWR_ON)? "On" : "Off" );
777
778 switch(q->soc_type)
779 {
780 case BT_SOC_DEFAULT:
781 if (readTrpState())
782 {
783 ALOGI("bt-vendor : resetting BT status");
784 hw_config(BT_VND_PWR_OFF);
785 }
786 retval = hw_config(nState);
787 if(nState == BT_VND_PWR_ON
788 && retval == 0
789 && is_hw_ready() == TRUE){
790 retval = 0;
791 }
792 else {
793 retval = -1;
794 }
795 break;
796 case BT_SOC_ROME:
797 case BT_SOC_AR3K:
798 case BT_SOC_CHEROKEE:
799 /* BT Chipset Power Control through Device Tree Node */
800 retval = bt_powerup(nState);
801 default:
802 break;
803 }
804 }
805 break;
806
807 case BT_VND_OP_FW_CFG: {
808 /* call hciattach to initalize the stack */
809 if (q->soc_type == BT_SOC_ROME) {
810 if (is_soc_initialized()) {
811 ALOGI("Bluetooth FW and transport layer are initialized");
812 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
813 } else {
814 ALOGE("bt_vendor_cbacks is null or SoC not initialized");
815 ALOGE("Error : hci, smd initialization Error");
816 retval = -1;
817 }
818 } else {
819 ALOGI("Bluetooth FW and transport layer are initialized");
820 q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
821 }
822 }
823 break;
824
825 case BT_VND_OP_SCO_CFG:
826 q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy
827 break;
828 #ifdef ENABLE_ANT
829 case BT_VND_OP_ANT_USERIAL_OPEN:
830 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN");
831 is_ant_req = true;
832 goto userial_open;
833 #endif
834 #ifdef FM_OVER_UART
835 case BT_VND_OP_FM_USERIAL_OPEN:
836 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_OPEN");
837 is_fm_req = true;
838 goto userial_open;
839 #endif
840 userial_open:
841 case BT_VND_OP_USERIAL_OPEN:
842 {
843 if (!param) {
844 ALOGE("opcode = %d: param is null", opcode_init);
845 break;
846 }
847 int (*fd_array)[] = (int (*)[]) param;
848 int idx, fd = -1, fd_filter = -1;
849 ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN");
850 switch(q->soc_type)
851 {
852 case BT_SOC_DEFAULT:
853 {
854 if(bt_hci_init_transport(q->fd) != -1){
855 int (*fd_array)[] = (int (*) []) param;
856
857 (*fd_array)[CH_CMD] = q->fd[0];
858 (*fd_array)[CH_EVT] = q->fd[0];
859 (*fd_array)[CH_ACL_OUT] = q->fd[1];
860 (*fd_array)[CH_ACL_IN] = q->fd[1];
861 }
862 else {
863 retval = -1;
864 break;
865 }
866 retval = 2;
867 }
868 break;
869 case BT_SOC_AR3K:
870 {
871 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
872 if (fd != -1) {
873 for (idx=0; idx < CH_MAX; idx++)
874 (*fd_array)[idx] = fd;
875 retval = 1;
876 }
877 else {
878 retval = -1;
879 break;
880 }
881
882 /* Vendor Specific Process should happened during userial_open process
883 After userial_open, rx read thread is running immediately,
884 so it will affect VS event read process.
885 */
886 if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0)
887 retval = -1;
888 }
889 break;
890 case BT_SOC_ROME:
891 {
892 wait_for_patch_download(is_ant_req);
893 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false);
894 if (!is_soc_initialized()) {
895 char* dlnd_inprog = is_ant_req ? "ant" : "bt";
896 if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) {
897 ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog);
898 }
899
900 fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg);
901 if (fd < 0) {
902 ALOGE("userial_vendor_open returns err");
903 retval = -1;
904 break;
905 }
906
907 /* Clock on */
908 userial_clock_operation(fd, USERIAL_OP_CLK_ON);
909
910 if(strcmp(emb_wp_mode, "true") == 0) {
911 property_get("ro.bluetooth.wipower", wipower_status, false);
912 if(strcmp(wipower_status, "true") == 0) {
913 check_embedded_mode(fd);
914 } else {
915 ALOGI("Wipower not enabled");
916 }
917 }
918 ALOGV("rome_soc_init is started");
919 property_set("wc_transport.soc_initialized", "0");
920 #ifdef READ_BT_ADDR_FROM_PROP
921 /*Give priority to read BD address from boot property*/
922 ignore_boot_prop = FALSE;
923 if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) {
924 ALOGV("BD address read from Boot property: %s\n", bd_addr);
925 tok = strtok(bd_addr, ":");
926 while (tok != NULL) {
927 ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16));
928 if (i>=6) {
929 ALOGE("bd property of invalid length");
930 ignore_boot_prop = TRUE;
931 break;
932 }
933 if (i == 6 && !ignore_boot_prop) {
934 ALOGV("Valid BD address read from prop");
935 memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
936 ignore_boot_prop = FALSE;
937 } else {
938 ALOGE("There are not enough tokens in BD addr");
939 ignore_boot_prop = TRUE;
940 break;
941 }
942 local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16);
943 tok = strtok(NULL, ":");
944 i++;
945 }
946 if (i == 6 && !ignore_boot_prop) {
947 ALOGV("Valid BD address read from prop");
948 memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr));
949 ignore_boot_prop = FALSE;
950 } else {
951 ALOGE("There are not enough tokens in BD addr");
952 ignore_boot_prop = TRUE;
953 }
954 }
955 else {
956 ALOGE("BD address boot property not set");
957 ignore_boot_prop = TRUE;
958 }
959 #endif //READ_BT_ADDR_FROM_PROP
960 /* Always read BD address from NV file */
961 if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr))
962 {
963 /* Since the BD address is configured in boot time We should not be here */
964 ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm");
965 }
966 if(rome_soc_init(fd, (char*)q->bdaddr)<0) {
967 retval = -1;
968 } else {
969 ALOGV("rome_soc_init is completed");
970 property_set("wc_transport.soc_initialized", "1");
971 skip_init = false;
972 }
973 }
974 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
975 ALOGE("%s: Failed to set property", __FUNCTION__);
976 }
977
978 property_set("wc_transport.clean_up","0");
979 if (retval != -1) {
980
981 retval = start_hci_filter();
982 if (retval < 0) {
983 ALOGE("%s: WCNSS_FILTER wouldn't have started in time\n", __func__);
984 } else {
985 #ifdef ENABLE_ANT
986 if (is_ant_req) {
987 ALOGI("%s: connect to ant channel", __func__);
988 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
989 }
990 else
991 #endif
992 {
993 ALOGI("%s: connect to bt channel", __func__);
994 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
995 }
996
997 if (fd_filter != -1) {
998 ALOGI("%s: received the socket fd: %d is_ant_req: %d is_fm_req: %d\n",
999 __func__, fd_filter, is_ant_req,is_fm_req);
1000 if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req && !is_fm_req) {
1001 if (chipset_ver >= ROME_VER_3_0) {
1002 /* get rome supported feature request */
1003 ALOGE("%s: %x08 %0x", __FUNCTION__,chipset_ver, ROME_VER_3_0);
1004 rome_get_addon_feature_list(fd_filter);
1005 }
1006 }
1007 if (!skip_init) {
1008 /*Skip if already sent*/
1009 enable_controller_log(fd_filter, (is_ant_req || is_fm_req) );
1010 skip_init = true;
1011 }
1012 for (idx=0; idx < CH_MAX; idx++)
1013 (*fd_array)[idx] = fd_filter;
1014 retval = 1;
1015 }
1016 else {
1017 if (is_ant_req)
1018 ALOGE("Unable to connect to ANT Server Socket!!!");
1019 else
1020 ALOGE("Unable to connect to BT Server Socket!!!");
1021 retval = -1;
1022 }
1023 }
1024 } else {
1025 if (q->soc_type == BT_SOC_ROME)
1026 ALOGE("Failed to initialize ROME Controller!!!");
1027 }
1028
1029 if (fd >= 0) {
1030 userial_clock_operation(fd, USERIAL_OP_CLK_OFF);
1031 /*Close the UART port*/
1032 close(fd);
1033 }
1034 }
1035 break;
1036 case BT_SOC_CHEROKEE:
1037 {
1038 property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false);
1039 retval = start_hci_filter();
1040 if (retval < 0) {
1041 ALOGE("WCNSS_FILTER wouldn't have started in time\n");
1042
1043 } else {
1044 #ifdef ENABLE_ANT
1045 if (is_ant_req) {
1046 ALOGI("%s: connect to ant channel", __func__);
1047 q->ant_fd = fd_filter = connect_to_local_socket("ant_sock");
1048 }
1049 else
1050 #endif
1051 #ifdef FM_OVER_UART
1052 if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) {
1053 ALOGI("%s: connect to fm channel", __func__);
1054 q->fm_fd = fd_filter = connect_to_local_socket("fm_sock");
1055 }
1056 else
1057 #endif
1058 {
1059 ALOGI("%s: connect to bt channel", __func__);
1060 vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock");
1061
1062 }
1063 if (fd_filter != -1) {
1064 ALOGV("%s: received the socket fd: %d \n",
1065 __func__, fd_filter);
1066
1067 for (idx=0; idx < CH_MAX; idx++) {
1068 (*fd_array)[idx] = fd_filter;
1069 }
1070 retval = 1;
1071 }
1072 else {
1073 #ifdef ENABLE_ANT
1074 if (is_ant_req)
1075 ALOGE("Unable to connect to ANT Server Socket!!!");
1076 else
1077 #endif
1078 #ifdef FM_OVER_UART
1079 if (is_fm_req)
1080 ALOGE("Unable to connect to FM Server Socket!!!");
1081 else
1082 #endif
1083 ALOGE("Unable to connect to BT Server Socket!!!");
1084 retval = -1;
1085 }
1086 }
1087 }
1088 break;
1089 default:
1090 ALOGE("Unknown soc_type: 0x%x", q->soc_type);
1091 break;
1092 }
1093 } break;
1094 #ifdef ENABLE_ANT
1095 case BT_VND_OP_ANT_USERIAL_CLOSE:
1096 {
1097 ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE");
1098 property_set("wc_transport.clean_up","1");
1099 if (q->ant_fd != -1) {
1100 ALOGE("closing ant_fd");
1101 close(q->ant_fd);
1102 q->ant_fd = -1;
1103 }
1104 }
1105 break;
1106 #endif
1107 #ifdef FM_OVER_UART
1108 case BT_VND_OP_FM_USERIAL_CLOSE:
1109 {
1110 ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE");
1111 property_set("wc_transport.clean_up","1");
1112 if (q->fm_fd != -1) {
1113 ALOGE("closing fm_fd");
1114 close(q->fm_fd);
1115 q->fm_fd = -1;
1116 }
1117 break;
1118 }
1119 #endif
1120 case BT_VND_OP_USERIAL_CLOSE:
1121 {
1122 ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type);
1123 switch(q->soc_type)
1124 {
1125 case BT_SOC_DEFAULT:
1126 bt_hci_deinit_transport(q->fd);
1127 break;
1128 case BT_SOC_ROME:
1129 case BT_SOC_AR3K:
1130 case BT_SOC_CHEROKEE:
1131 {
1132 property_set("wc_transport.clean_up","1");
1133 userial_vendor_close();
1134 break;
1135 }
1136 default:
1137 ALOGE("Unknown soc_type: 0x%x", q->soc_type);
1138 break;
1139 }
1140 }
1141 break;
1142
1143 case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
1144 {
1145 if (!param) {
1146 ALOGE("opcode = %d: param is null", opcode_init);
1147 break;
1148 }
1149 uint32_t *timeout_ms = (uint32_t *) param;
1150 *timeout_ms = 1000;
1151 }
1152
1153 break;
1154
1155 case BT_VND_OP_LPM_SET_MODE:
1156 if (q->soc_type == BT_SOC_AR3K) {
1157 if (!param) {
1158 ALOGE("opcode = %d: param is null", opcode_init);
1159 break;
1160 }
1161 uint8_t *mode = (uint8_t *) param;
1162
1163 if (*mode) {
1164 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0);
1165 }
1166 else {
1167 lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0);
1168 }
1169 q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS);
1170 } else {
1171 int lpm_result = BT_VND_OP_RESULT_SUCCESS;
1172
1173 property_get("persist.service.bdroid.lpmcfg", lpm_config, "all");
1174 ALOGI("%s: property_get: persist.service.bdroid.lpmcfg: %s",
1175 __func__, lpm_config);
1176
1177 if (!strcmp(lpm_config, "all")) {
1178 // respond with success since we want to hold wake lock through LPM
1179 lpm_result = BT_VND_OP_RESULT_SUCCESS;
1180 }
1181 else {
1182 lpm_result = BT_VND_OP_RESULT_FAIL;
1183 }
1184
1185 q->cb->lpm_cb(lpm_result);
1186 }
1187 break;
1188
1189 case BT_VND_OP_LPM_WAKE_SET_STATE: {
1190 switch(q->soc_type) {
1191 case BT_SOC_CHEROKEE:
1192 case BT_SOC_ROME: {
1193 if (!param) {
1194 ALOGE("opcode = %d: param is null", opcode_init);
1195 break;
1196 }
1197 uint8_t *state = (uint8_t *) param;
1198 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
1199 BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT;
1200
1201 if (wake_assert == 0)
1202 ALOGV("ASSERT: Waking up BT-Device");
1203 else if (wake_assert == 1)
1204 ALOGV("DEASSERT: Allowing BT-Device to Sleep");
1205
1206 #ifdef QCOM_BT_SIBS_ENABLE
1207 ALOGI("Invoking HCI H4 callback function");
1208 q->cb->lpm_set_state_cb(wake_assert);
1209 #endif
1210 }
1211 break;
1212 case BT_SOC_AR3K: {
1213 if (!param) {
1214 ALOGE("opcode = %d: param is null", opcode_init);
1215 break;
1216 }
1217 uint8_t *state = (uint8_t *) param;
1218 uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \
1219 UPIO_ASSERT : UPIO_DEASSERT;
1220 lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0);
1221 }
1222 case BT_SOC_DEFAULT:
1223 break;
1224 default:
1225 ALOGE("Unknown soc_type: 0x%x", q->soc_type);
1226 break;
1227 }
1228 }
1229 break;
1230 case BT_VND_OP_EPILOG: {
1231 #if (HW_NEED_END_WITH_HCI_RESET == FALSE)
1232 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1233 #else
1234 switch(q->soc_type)
1235 {
1236 case BT_SOC_CHEROKEE:
1237 case BT_SOC_ROME:
1238 {
1239 char value[PROPERTY_VALUE_MAX] = {'\0'};
1240 property_get("wc_transport.hci_filter_status", value, "0");
1241 if(is_soc_initialized()&& (strcmp(value,"1") == 0))
1242 {
1243 __hw_epilog_process();
1244 }
1245 else
1246 {
1247 q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
1248 }
1249 }
1250 break;
1251 default:
1252 __hw_epilog_process();
1253 break;
1254 }
1255 #endif
1256 }
1257 break;
1258 case BT_VND_OP_GET_LINESPEED:
1259 {
1260 retval = -1;
1261 if(!is_soc_initialized()) {
1262 ALOGE("BT_VND_OP_GET_LINESPEED: error"
1263 " - transport driver not initialized!");
1264 break;
1265 }
1266
1267 switch(q->soc_type)
1268 {
1269 case BT_SOC_CHEROKEE:
1270 retval = 3200000;
1271 break;
1272 case BT_SOC_ROME:
1273 retval = 3000000;
1274 break;
1275 default:
1276 retval = userial_vendor_get_baud();
1277 break;
1278 }
1279 break;
1280 }
1281 }
1282
1283 out:
1284 ALOGV("--%s", __FUNCTION__);
1285 return retval;
1286 }
1287
op(bt_vendor_opcode_t opcode,void * param)1288 static int op(bt_vendor_opcode_t opcode, void *param)
1289 {
1290 int ret;
1291 ALOGV("++%s", __FUNCTION__);
1292 pthread_mutex_lock(&q_lock);
1293 if (!q) {
1294 ALOGE("op called with NULL context");
1295 ret = -BT_STATUS_INVAL;
1296 goto out;
1297 }
1298 ret = __op(opcode, param);
1299 out:
1300 pthread_mutex_unlock(&q_lock);
1301 ALOGV("--%s ret = 0x%x", __FUNCTION__, ret);
1302 return ret;
1303 }
1304
ssr_cleanup(int reason)1305 static void ssr_cleanup(int reason)
1306 {
1307 int pwr_state = BT_VND_PWR_OFF;
1308 int ret;
1309 unsigned char trig_ssr = 0xEE;
1310
1311 ALOGI("++%s", __FUNCTION__);
1312
1313 pthread_mutex_lock(&q_lock);
1314 if (!q) {
1315 ALOGE("ssr_cleanup called with NULL context");
1316 goto out;
1317 }
1318 if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) {
1319 ALOGE("Failed to set property");
1320 }
1321
1322 if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) {
1323 #ifdef ENABLE_ANT
1324 /*Indicate to filter by sending special byte */
1325 if (reason == CMD_TIMEOUT) {
1326 trig_ssr = 0xEE;
1327 ret = write (vnd_userial.fd, &trig_ssr, 1);
1328 ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s",
1329 ret, strerror(errno));
1330
1331 if (is_debug_force_special_bytes()) {
1332 /*
1333 * Then we should send special byte to crash SOC in
1334 * WCNSS_Filter, so we do not need to power off UART here.
1335 */
1336 goto out;
1337 }
1338 }
1339
1340 /* Close both ANT channel */
1341 __op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
1342 #endif
1343 /* Close both BT channel */
1344 __op(BT_VND_OP_USERIAL_CLOSE, NULL);
1345
1346 #ifdef FM_OVER_UART
1347 __op(BT_VND_OP_FM_USERIAL_CLOSE, NULL);
1348 #endif
1349 /*CTRL OFF twice to make sure hw
1350 * turns off*/
1351 #ifdef ENABLE_ANT
1352 __op(BT_VND_OP_POWER_CTRL, &pwr_state);
1353 #endif
1354 }
1355 /*Generally switching of chip should be enough*/
1356 __op(BT_VND_OP_POWER_CTRL, &pwr_state);
1357
1358 out:
1359 pthread_mutex_unlock(&q_lock);
1360 ALOGI("--%s", __FUNCTION__);
1361 }
1362
1363 /** Closes the interface */
cleanup(void)1364 static void cleanup(void)
1365 {
1366 ALOGI("cleanup");
1367
1368 pthread_mutex_lock(&q_lock);
1369 q->cb = NULL;
1370 free(q);
1371 q = NULL;
1372 pthread_mutex_unlock(&q_lock);
1373
1374 #ifdef WIFI_BT_STATUS_SYNC
1375 isInit = 0;
1376 #endif /* WIFI_BT_STATUS_SYNC */
1377 }
1378
1379 /* Check for one of the cients ANT/BT patch download is already in
1380 ** progress if yes wait till complete
1381 */
wait_for_patch_download(bool is_ant_req)1382 void wait_for_patch_download(bool is_ant_req) {
1383 ALOGV("%s:", __FUNCTION__);
1384 char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
1385 while (1) {
1386 property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
1387
1388 if(is_ant_req && !(strcmp(inProgress,"bt"))) {
1389 //ANT request, wait for BT to finish
1390 usleep(50000);
1391 }
1392 else if(!is_ant_req && !(strcmp(inProgress,"ant"))) {
1393 //BT request, wait for ANT to finish
1394 usleep(50000);
1395 }
1396 else {
1397 ALOGI("%s: patch download completed", __FUNCTION__);
1398 break;
1399 }
1400 }
1401 }
1402
is_download_progress()1403 bool is_download_progress () {
1404 char inProgress[PROPERTY_VALUE_MAX] = {'\0'};
1405 bool retval = false;
1406
1407 ALOGV("%s:", __FUNCTION__);
1408
1409 if ((q->soc_type = get_bt_soc_type()) < 0) {
1410 ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__);
1411 return -1;
1412 }
1413
1414 switch(q->soc_type)
1415 {
1416 case BT_SOC_ROME:
1417 ALOGI("%s: ROME case", __func__);
1418 property_get("wc_transport.patch_dnld_inprog", inProgress, "null");
1419 if(strcmp(inProgress,"null") == 0) {
1420 retval = false;
1421 } else {
1422 retval = true;
1423 }
1424 break;
1425 case BT_SOC_CHEROKEE:
1426 ALOGI("%s: CHEROKEE case", __func__);
1427 break;
1428 case BT_SOC_DEFAULT:
1429 break;
1430 default:
1431 ALOGE("Unknown btSocType: 0x%x", q->soc_type);
1432 break;
1433 }
1434 return retval;
1435 }
1436
is_debug_force_special_bytes()1437 static bool is_debug_force_special_bytes() {
1438 int ret = 0;
1439 char value[PROPERTY_VALUE_MAX] = {'\0'};
1440 bool enabled = false;
1441 #ifdef ENABLE_DBG_FLAGS
1442 enabled = true;
1443 #endif
1444
1445 ret = property_get("wc_transport.force_special_byte", value, NULL);
1446
1447 if (ret) {
1448 enabled = (strcmp(value, "false") ==0) ? false : true;
1449 ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ",
1450 __func__, value, enabled);
1451 }
1452
1453 return enabled;
1454 }
1455
1456 // Entry point of DLib
1457 const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
1458 sizeof(bt_vendor_interface_t),
1459 init,
1460 op,
1461 cleanup,
1462 ssr_cleanup
1463 };
1464