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