10ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/* 20ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Copyright 2012 The Android Open Source Project 30ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Copyright (c) 2013, The Linux Foundation. All rights reserved. 40ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Not a Contribution. 50ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 60ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Licensed under the Apache License, Version 2.0 (the "License"); 70ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * you may not use this file except in compliance with the License. 80ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * You may obtain a copy of the License at 90ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * http://www.apache.org/licenses/LICENSE-2.0 110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Unless required by applicable law or agreed to in writing, software 130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * distributed under the License is distributed on an "AS IS" BASIS, 140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * See the License for the specific language governing permissions and 160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * limitations under the License. 170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel */ 180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Filename: bt_vendor_qcom.c 220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * Description: vendor specific library implementation 240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * 250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ******************************************************************************/ 260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define LOG_TAG "bt_vendor" 270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define BLUETOOTH_MAC_ADDR_BOOT_PROPERTY "ro.boot.btmacaddr" 280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <utils/Log.h> 300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <cutils/properties.h> 310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <fcntl.h> 320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <termios.h> 330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "bt_vendor_qcom.h" 340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "hci_uart.h" 350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "hci_smd.h" 36bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel#include <sys/ioctl.h> 370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <sys/socket.h> 380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <cutils/sockets.h> 390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <linux/un.h> 400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "bt_vendor_persist.h" 410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "hw_rome.h" 420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "bt_vendor_lib.h" 430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define WAIT_TIMEOUT 200000 440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define BT_VND_OP_GET_LINESPEED 30 450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define STOP_WCNSS_FILTER 0xDD 4741464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel#define STOP_WAIT_TIMEOUT 1000 480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define SOC_INIT_PROPERTY "wc_transport.soc_initialized" 500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define BT_VND_FILTER_START "wc_transport.start_hci" 520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define CMD_TIMEOUT 0x22 540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic void wait_for_patch_download(bool is_ant_req); 560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic bool is_debug_force_special_bytes(void); 570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint connect_to_local_socket(char* name); 580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Externs 600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel******************************************************************************/ 610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelextern int hw_config(int nState); 620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelextern int is_hw_ready(); 630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelextern int chipset_ver; 640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Variables 670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel******************************************************************************/ 685752ddcecf884adefc166873565da60e70f59400Thierry Strudelstruct bt_qcom_struct *q = NULL; 6920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelpthread_mutex_t q_lock = PTHREAD_MUTEX_INITIALIZER; 700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint userial_clock_operation(int fd, int cmd); 720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti); 730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint userial_vendor_get_baud(void); 740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint readTrpState(); 750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelvoid lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity); 760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelbool is_download_progress(); 770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic const tUSERIAL_CFG userial_init_cfg = 790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1), 810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel USERIAL_BAUD_115200 820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel}; 830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#if (HW_NEED_END_WITH_HCI_RESET == TRUE) 8520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelvoid __hw_epilog_process(void); 860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <string.h> 900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <errno.h> 910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include <dlfcn.h> 920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#include "cutils/properties.h" 930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic const char WIFI_PROP_NAME[] = "wlan.driver.status"; 950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic const char SERVICE_PROP_NAME[] = "bluetooth.hsic_ctrl"; 960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic const char BT_STATUS_NAME[] = "bluetooth.enabled"; 970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic const char WIFI_SERVICE_PROP[] = "wlan.hsic_ctrl"; 980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#define WIFI_BT_STATUS_LOCK "/data/connectivity/wifi_bt_lock" 1000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint isInit=0; 1010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /* WIFI_BT_STATUS_SYNC */ 1020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelbool is_soc_initialized(void); 1030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 1050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Local type definitions 1060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel******************************************************************************/ 1070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/****************************************************************************** 1090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** Functions 1100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel******************************************************************************/ 1110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 1120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_semaphore_create(void) 1130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int fd; 1150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = open(WIFI_BT_STATUS_LOCK, O_RDONLY); 1170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd < 0) 1190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("can't create file\n"); 1200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return fd; 1220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_semaphore_get(int fd) 1250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret; 1270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd < 0) 1290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = flock(fd, LOCK_EX); 1320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret != 0) { 1330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("can't hold lock: %s\n", strerror(errno)); 1340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return ret; 1380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_semaphore_release(int fd) 1410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret; 1430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd < 0) 1450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = flock(fd, LOCK_UN); 1480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret != 0) { 1490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("can't release lock: %s\n", strerror(errno)); 1500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return ret; 1540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_semaphore_destroy(int fd) 1570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd < 0) 1590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 1600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return close (fd); 1620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint bt_wait_for_service_done(void) 1650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char service_status[PROPERTY_VALUE_MAX]; 1670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int count = 30; 1680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: check\n", __func__); 1700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* wait for service done */ 1720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel while (count-- > 0) { 1730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get(WIFI_SERVICE_PROP, service_status, NULL); 1740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strcmp(service_status, "") != 0) { 1760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(200000); 1770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 1780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 1790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 1810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return 0; 1830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 1840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /* WIFI_BT_STATUS_SYNC */ 1860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/** Get Bluetooth SoC type from system setting */ 1880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic int get_bt_soc_type() 1890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 1900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret = 0; 1910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char bt_soc_type[PROPERTY_VALUE_MAX]; 1920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : get_bt_soc_type"); 1940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 1950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL); 1960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret != 0) { 1970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type); 1980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!strncasecmp(bt_soc_type, "rome", sizeof("rome"))) { 1990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return BT_SOC_ROME; 2000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) { 2020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return BT_SOC_CHEROKEE; 2030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k"))) { 2050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return BT_SOC_AR3K; 2060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (!strncasecmp(bt_soc_type, "cherokee", sizeof("cherokee"))) { 2080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return BT_SOC_CHEROKEE; 2090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 2110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("qcom.bluetooth.soc not set, so using default.\n"); 2120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return BT_SOC_DEFAULT; 2130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 2160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Failed to get soc type", __FUNCTION__); 2170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = BT_SOC_DEFAULT; 2180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return ret; 2210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 2220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelbool can_perform_action(char action) { 2240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool can_perform = false; 2250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char ref_count[PROPERTY_VALUE_MAX]; 2260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 2270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int value, ret; 2280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("wc_transport.ref_count", ref_count, "0"); 2300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel value = atoi(ref_count); 2320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: ref_count: %s\n",__func__, ref_count); 2330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(action == '1') { 2350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: on : value is: %d", __func__, value); 2360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(value == 1) 2370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 2380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((is_soc_initialized() == true) 2390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel || is_download_progress() || get_bt_soc_type() == BT_SOC_CHEROKEE) 2400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 2410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel value++; 2420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: on : value is incremented to : %d", __func__, value); 2430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 2460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 2470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel value++; 2480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (value == 1) 2510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel can_perform = true; 2520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (value > 3) 2530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return false; 2540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 2560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: off : value is: %d", __func__, value); 2570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (--value <= 0) { 2580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: BT turn off twice before BT On(ref_count=%d)\n", 2590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel __func__, value); 2600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel value = 0; 2610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel can_perform = true; 2620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel snprintf(ref_count, 3, "%d", value); 2660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: updated ref_count is: %s", __func__, ref_count); 2670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_set("wc_transport.ref_count", ref_count); 2690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret < 0) { 2700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Error while updating property: %d\n", __func__, ret); 2710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return false; 2720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 2730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s returning %d", __func__, can_perform); 2740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return can_perform; 2750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 2760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelvoid stop_hci_filter() { 2780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char value[PROPERTY_VALUE_MAX] = {'\0'}; 2790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int retval, filter_ctrl, i; 2800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char stop_val = STOP_WCNSS_FILTER; 2810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int soc_type = BT_SOC_DEFAULT; 2820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: Entry ", __func__); 2840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 2850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((soc_type = get_bt_soc_type()) == BT_SOC_CHEROKEE) { 28641464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel property_get("wc_transport.hci_filter_status", value, "0"); 28741464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel if (strcmp(value, "0") == 0) { 28841464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel ALOGI("%s: hci_filter has been stopped already", __func__); 28941464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel } 29041464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel else { 29141464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel filter_ctrl = connect_to_local_socket("wcnssfilter_ctrl"); 29241464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel if (filter_ctrl < 0) { 29341464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel ALOGI("%s: Error while connecting to CTRL_SOCK, filter should stopped: %d", 29441464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel __func__, filter_ctrl); 29541464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel } 29641464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel else { 29741464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel retval = write(filter_ctrl, &stop_val, 1); 29841464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel if (retval != 1) { 29941464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel ALOGI("%s: problem writing to CTRL_SOCK, ignore: %d", __func__, retval); 30041464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel //Ignore and fallback 30141464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel } 30241464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel 30341464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel close(filter_ctrl); 3040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Ensure Filter is closed by checking the status before 3080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel RFKILL 0 operation. this should ideally comeout very 3090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel quick */ 31041464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel for(i=0; i<500; i++) { 31141464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel property_get(BT_VND_FILTER_START, value, "false"); 31241464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel if (strcmp(value, "false") == 0) { 3130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: WCNSS_FILTER stopped", __func__); 31441464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel usleep(STOP_WAIT_TIMEOUT * 10); 3150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 3160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 31741464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel /*sleep of 1ms, This should give enough time for FILTER to 3180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel exit with all necessary cleanup*/ 3190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(STOP_WAIT_TIMEOUT); 3200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*Never use SIGKILL to stop the filter*/ 3240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Filter will be stopped by below two conditions 3250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel - by Itself, When it realizes there are no CONNECTED clients 3260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel - Or through STOP_WCNSS_FILTER byte on Control socket 3270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel both of these ensure clean shutdown of chip 3280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel */ 3290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //property_set(BT_VND_FILTER_START, "false"); 3300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else if (soc_type == BT_SOC_ROME) { 3310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set(BT_VND_FILTER_START, "false"); 3320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 3330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: Unknown soc type %d, Unexpected!", __func__, soc_type); 3340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: Exit ", __func__); 3370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 3380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint start_hci_filter() { 3400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: Entry ", __func__); 3410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int i, init_success = -1; 3420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char value[PROPERTY_VALUE_MAX] = {'\0'}; 3430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get(BT_VND_FILTER_START, value, false); 3450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strcmp(value, "true") == 0) { 3470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: hci_filter has been started already", __func__); 3480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //Filter should have been started OR in the process of initializing 3490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //Make sure of hci_filter_status and return the state based on it 3500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 35169ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel property_set("wc_transport.clean_up","0"); 3520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.hci_filter_status", "0"); 3530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set(BT_VND_FILTER_START, "true"); 3540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: %s set to true ", __func__, BT_VND_FILTER_START ); 3550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*If there are back to back ON requests from different clients, 3580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel All client should come and stuck in this while loop till FILTER 3590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel comesup and ready to accept the connections */ 3600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //sched_yield(); 3610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for(i=0; i<45; i++) { 3620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("wc_transport.hci_filter_status", value, "0"); 3630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strcmp(value, "1") == 0) { 3640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel init_success = 1; 3650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 3660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 3670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(WAIT_TIMEOUT); 3680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 3700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("start_hcifilter status:%d after %f seconds \n", init_success, 0.2*i); 3710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: Exit ", __func__); 3730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return init_success; 3740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 3750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 37620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel/* 37720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel * Bluetooth Controller power up or shutdown, this function is called with 37820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel * q_lock held and q is non-NULL 37920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel */ 3800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic int bt_powerup(int en ) 3810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 3820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char rfkill_type[64], *enable_ldo_path = NULL; 3830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char type[16], enable_ldo[6]; 384bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel int fd = 0, size, i, ret, fd_ldo, fd_btpower; 3850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char disable[PROPERTY_VALUE_MAX]; 3870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char state; 3880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char on = (en)?'1':'0'; 3890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 3910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char wifi_status[PROPERTY_VALUE_MAX]; 3920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int lock_fd; 3930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /*WIFI_BT_STATUS_SYNC*/ 3940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt_powerup: %c", on); 3960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 3970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Check if rfkill has been disabled */ 3980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_get("ro.rfkilldisabled", disable, "0"); 3990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!ret ){ 4000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Couldn't get ro.rfkilldisabled (%d)", ret); 4010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* In case rfkill disabled, then no control power*/ 4040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strcmp(disable, "1") == 0) { 4050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("ro.rfkilldisabled : %s", disable); 4060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 4100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel lock_fd = bt_semaphore_create(); 4110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_get(lock_fd); 4120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_wait_for_service_done(); 4130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 4140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Assign rfkill_id and find bluetooth rfkill state path*/ 4165752ddcecf884adefc166873565da60e70f59400Thierry Strudel for(i = 0; (q->rfkill_id == -1) && (q->rfkill_state == NULL); i++) 4170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel snprintf(rfkill_type, sizeof(rfkill_type), "/sys/class/rfkill/rfkill%d/type", i); 4190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((fd = open(rfkill_type, O_RDONLY)) < 0) 4200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("open(%s) failed: %s (%d)\n", rfkill_type, strerror(errno), errno); 4220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 4240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 4250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 4260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 4270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel size = read(fd, &type, sizeof(type)); 4310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 4320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((size >= 9) && !memcmp(type, "bluetooth", 9)) 4340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4355752ddcecf884adefc166873565da60e70f59400Thierry Strudel asprintf(&q->rfkill_state, "/sys/class/rfkill/rfkill%d/state", q->rfkill_id = i); 4360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 4370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Get rfkill State to control */ 4415752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->rfkill_state != NULL) 4420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4435752ddcecf884adefc166873565da60e70f59400Thierry Strudel if ((fd = open(q->rfkill_state, O_RDWR)) < 0) 4440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4455752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("open(%s) for write failed: %s (%d)", q->rfkill_state, strerror(errno), errno); 4460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 4470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 4480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 4490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 4500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(can_perform_action(on) == false) { 4550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s:can't perform action as it is being used by other clients", __func__); 4560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 4570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 4580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 4590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 4600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel goto done; 4610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4625752ddcecf884adefc166873565da60e70f59400Thierry Strudel ret = asprintf(&enable_ldo_path, "/sys/class/rfkill/rfkill%d/device/extldo", q->rfkill_id); 4630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if( (ret < 0 ) || (enable_ldo_path == NULL) ) 4640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 4650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Memory Allocation failure"); 4660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((fd_ldo = open(enable_ldo_path, O_RDWR)) < 0) { 4690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("open(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 4700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel size = read(fd_ldo, &enable_ldo, sizeof(enable_ldo)); 4730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd_ldo); 4740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (size <= 0) { 4750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("read(%s) failed: %s (%d)", enable_ldo_path, strerror(errno), errno); 4760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 4770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!memcmp(enable_ldo, "true", 4)) { 4790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("External LDO has been configured"); 4800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_set("wc_transport.extldo", "enabled"); 4810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret < 0) { 4820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: Not able to set property wc_transport.extldo\n", __func__); 4830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4845752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->enable_extldo = TRUE; 4850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(on == '0'){ 4880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Stopping HCI filter as part of CTRL:OFF"); 4890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel stop_hci_filter(); 4900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.soc_initialized", "0"); 4910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 4920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 4935752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->soc_type >= BT_SOC_CHEROKEE && q->soc_type < BT_SOC_RESERVED) { 494bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel ALOGI("open bt power devnode,send ioctl power op :%d ",en); 495bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel fd_btpower = open(BT_PWR_CNTRL_DEVICE, O_RDWR, O_NONBLOCK); 496bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel if (fd_btpower < 0) { 497bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel ALOGE("\nfailed to open bt device error = (%s)\n",strerror(errno)); 4980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 499bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel bt_semaphore_release(lock_fd); 500bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel bt_semaphore_destroy(lock_fd); 5010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 502bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel return -1; 503bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel } 504bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel ret = ioctl(fd_btpower, BT_CMD_PWR_CTRL, (unsigned long)en); 505bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel if (ret < 0) { 506bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel ALOGE(" ioctl failed to power control:%d error =(%s)",ret,strerror(errno)); 5070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 508bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel close(fd_btpower); 509bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel } else { 510bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel ALOGI("Write %c to rfkill\n", on); 511bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel /* Write value to control rfkill */ 512bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel if(fd >= 0) { 513bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel if ((size = write(fd, &on, 1)) < 0) { 5145752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("write(%s) failed: %s (%d)", q->rfkill_state, strerror(errno), errno); 515bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 516bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel bt_semaphore_release(lock_fd); 517bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel bt_semaphore_destroy(lock_fd); 518bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel#endif 519bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel return -1; 520bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel } 521bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel } 522bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel } 5230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 5240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* query wifi status */ 5250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get(WIFI_PROP_NAME, wifi_status, ""); 5260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 5270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("bt get wifi status: %s, isInit: %d\n", wifi_status, isInit); 5280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 5290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* If wlan driver is not loaded, and bt is changed from off => on */ 5300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strncmp(wifi_status, "unloaded", strlen("unloaded")) == 0 || strlen(wifi_status) == 0) { 5310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (on == '1') { 5320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: BT_VND_PWR_ON\n", __func__); 5330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(property_set(SERVICE_PROP_NAME, "load_wlan") < 0) { 5340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 5350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 5360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 5370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 5380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 5390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 5400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 5410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (isInit == 0 && on == '0') { 5420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: BT_VND_PWR_OFF\n", __func__); 5430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(property_set(SERVICE_PROP_NAME, "unbind_hsic") < 0) { 5440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s Property setting failed", SERVICE_PROP_NAME); 5450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 5460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 5470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 5480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 5490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 5500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 5510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 5520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 5530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (isInit == 0 && on == '0') 5540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set(BT_STATUS_NAME, "false"); 5550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if (on == '1') 5560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set(BT_STATUS_NAME, "true"); 5570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 5580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_release(lock_fd); 5590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bt_semaphore_destroy(lock_fd); 5600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /* WIFI_BT_STATUS_SYNC */ 5610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 5620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudeldone: 5630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd >= 0) 5640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 5650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return 0; 5660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 5670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 56820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic inline void soc_init(int soc_type) 56920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel{ 57020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel switch (soc_type) 57120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel { 57220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_CHEROKEE: 57320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_ROME: 57420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_AR3K: 57520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("bt-vendor : Initializing UART transport layer"); 57620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel userial_vendor_init(); 57720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 57820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_DEFAULT: 57920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 58020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel default: 58120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("Unknown soc yype: %d", soc_type); 58220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 58320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 58420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel} 58520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 58620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel/* Copy BD Address as little-endian byte order */ 58720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic inline void le2bd(unsigned char *src, unsigned char *dst) 58820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel{ 58920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel int i; 59020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel for (i = 0; i < 6; i++) 59120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel dst[i] = src[5-i]; 59220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel} 59320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 59420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic inline void print_bdaddr(unsigned char *addr) 59520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel{ 59620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("BD Address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", addr[0], addr[1], 59720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel addr[2], addr[3], addr[4], addr[5]); 59820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel} 59920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 6000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/***************************************************************************** 6010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** 6020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS 6030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** 6040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel*****************************************************************************/ 6050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 60620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic int init(const bt_vendor_callbacks_t *cb, unsigned char *bdaddr) 6070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 608c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel char prop[PROPERTY_VALUE_MAX] = {0}; 6095752ddcecf884adefc166873565da60e70f59400Thierry Strudel struct bt_qcom_struct *temp = NULL; 61020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel int ret = BT_STATUS_SUCCESS, i; 6110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 61220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("++%s", __FUNCTION__); 6130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 61420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!cb || !bdaddr) { 61520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("Invalid input args cb %p bdaddr %p", cb, bdaddr); 61620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ret = -BT_STATUS_INVAL; 61720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel goto out; 6180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 6190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 6205752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp = (struct bt_qcom_struct *) malloc(sizeof(*q)); 6215752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (!temp) { 6225752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("Failed to allocate memory. err %s(%d)", strerror(errno), errno); 6235752ddcecf884adefc166873565da60e70f59400Thierry Strudel ret = -BT_STATUS_NOMEM; 6245752ddcecf884adefc166873565da60e70f59400Thierry Strudel goto out; 6255752ddcecf884adefc166873565da60e70f59400Thierry Strudel } 6265752ddcecf884adefc166873565da60e70f59400Thierry Strudel memset(temp, 0, sizeof(*temp)); 62720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 6285752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->rfkill_id = -1; 6295752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->enable_extldo = FALSE; 6301414527307ab6aae2c497b3d2122278cb9ca1aa1Frank Barchard temp->cb = (bt_vendor_callbacks_t*)cb; 6315752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->ant_fd = -1; 6325752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->soc_type = get_bt_soc_type(); 6335752ddcecf884adefc166873565da60e70f59400Thierry Strudel soc_init(temp->soc_type); 6345752ddcecf884adefc166873565da60e70f59400Thierry Strudel 6355752ddcecf884adefc166873565da60e70f59400Thierry Strudel le2bd(bdaddr, temp->bdaddr); 6365752ddcecf884adefc166873565da60e70f59400Thierry Strudel print_bdaddr(temp->bdaddr); 637c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel snprintf(prop, sizeof(prop), "%02x:%02x:%02x:%02x:%02x:%02x", 6385752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->bdaddr[0], temp->bdaddr[1], temp->bdaddr[2], 6395752ddcecf884adefc166873565da60e70f59400Thierry Strudel temp->bdaddr[3], temp->bdaddr[4], temp->bdaddr[5]); 640c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel ret = property_set("wc_transport.stack_bdaddr", prop); 641c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel if (ret < 0) { 642c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel ALOGE("Failed to set wc_transport.stack_bdaddr prop, ret = %d", ret); 643c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel ret = -BT_STATUS_PROP_FAILURE; 644c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel goto out; 645c326d170da6532d78df3fa18ffacfd9574841a90Thierry Strudel } 64620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 64720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel/* TODO: Move these fields inside bt_qcom context */ 6480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 6490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel isInit = 1; 6500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /* WIFI_BT_STATUS_SYNC */ 6510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 65220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /* Everything successful */ 6535752ddcecf884adefc166873565da60e70f59400Thierry Strudel q = temp; 65420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel return ret; 65520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 65620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelout: 6575752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (temp) 6585752ddcecf884adefc166873565da60e70f59400Thierry Strudel free(temp); 65920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("--%s ret %d", __FUNCTION__, ret); 66020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel return ret; 6610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 6620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 6630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef READ_BT_ADDR_FROM_PROP 6640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic bool validate_tok(char* bdaddr_tok) { 6650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int i = 0; 6660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool ret; 6670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 6680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (strlen(bdaddr_tok) != 2) { 6690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = FALSE; 6700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Invalid token length"); 6710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 6720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = TRUE; 6730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for (i=0; i<2; i++) { 6740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if ((bdaddr_tok[i] >= '0' && bdaddr_tok[i] <= '9') || 6750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (bdaddr_tok[i] >= 'A' && bdaddr_tok[i] <= 'F') || 6760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (bdaddr_tok[i] >= 'a' && bdaddr_tok[i] <= 'f')) { 6770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = TRUE; 6780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: tok %s @ %d is good", __func__, bdaddr_tok, i); 6790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 6800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = FALSE; 6810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("invalid character in tok: %s at ind: %d", bdaddr_tok, i); 6820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 6830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 6840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 6850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 6860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return ret; 6870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 6880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /*READ_BT_ADDR_FROM_PROP*/ 6890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 6900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelint connect_to_local_socket(char* name) { 6910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel socklen_t len; int sk = -1; 6920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 6930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: ACCEPT ", __func__); 6940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel sk = socket(AF_LOCAL, SOCK_STREAM, 0); 6950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (sk < 0) { 6960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Socket creation failure"); 6970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 6980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 6990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(socket_local_client_connect(sk, name, 7010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) 7020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 7030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("failed to connect (%s)", strerror(errno)); 7040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(sk); 7050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel sk = -1; 7060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 7070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Connection succeeded\n", __func__); 7080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return sk; 7100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 7110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelbool is_soc_initialized() { 7130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool init = false; 7140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char init_value[PROPERTY_VALUE_MAX]; 7150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret; 7160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : is_soc_initialized"); 7180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_get(SOC_INIT_PROPERTY, init_value, NULL); 7200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret != 0) { 7210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s set to %s\n", SOC_INIT_PROPERTY, init_value); 7220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!strncasecmp(init_value, "1", sizeof("1"))) { 7230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel init = true; 7240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 7270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Failed to get %s", __FUNCTION__, SOC_INIT_PROPERTY); 7280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return init; 7310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 7320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 73341464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel/* flavor of op without locks */ 734d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanusstatic int op(bt_vendor_opcode_t opcode, void *param) 7350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 73620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel int retval = BT_STATUS_SUCCESS; 7370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int nCnt = 0; 7380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int nState = -1; 7390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool is_ant_req = false; 7400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool is_fm_req = false; 7410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char wipower_status[PROPERTY_VALUE_MAX]; 7420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char emb_wp_mode[PROPERTY_VALUE_MAX]; 7430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char bt_version[PROPERTY_VALUE_MAX]; 744190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel char lpm_config[PROPERTY_VALUE_MAX]; 7450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool ignore_boot_prop = TRUE; 7460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef READ_BT_ADDR_FROM_PROP 7470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int i = 0; 7480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel static char bd_addr[PROPERTY_VALUE_MAX]; 7490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel uint8_t local_bd_addr_from_prop[6]; 7500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char* tok; 7510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 7520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool skip_init = true; 7530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int opcode_init = opcode; 75420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGV("++%s opcode %d", __FUNCTION__, opcode); 7550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel switch(opcode_init) 7570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 7580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 7590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case FM_VND_OP_POWER_CTRL: 7600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 7610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel is_fm_req = true; 7620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_soc_initialized()) { 7630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel // add any FM specific actions if needed in future 7640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 7650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 7680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_POWER_CTRL: 7690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 77020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 77120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 77220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 77320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 7740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel nState = *(int *) param; 7750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_POWER_CTRL: %s", 7760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (nState == BT_VND_PWR_ON)? "On" : "Off" ); 7770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 7785752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 7790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 7800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_DEFAULT: 7810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (readTrpState()) 7820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 7830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : resetting BT status"); 7840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel hw_config(BT_VND_PWR_OFF); 7850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = hw_config(nState); 7870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(nState == BT_VND_PWR_ON 7880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel && retval == 0 7890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel && is_hw_ready() == TRUE){ 7900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 0; 7910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 7930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 7940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 7950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 7960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 7970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_AR3K: 7980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 7990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* BT Chipset Power Control through Device Tree Node */ 80020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel retval = bt_powerup(nState); 8010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 8020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 80720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_VND_OP_FW_CFG: { 80820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /* call hciattach to initalize the stack */ 8095752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->soc_type == BT_SOC_ROME) { 81020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (is_soc_initialized()) { 81120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("Bluetooth FW and transport layer are initialized"); 8125752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 81320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } else { 81420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("bt_vendor_cbacks is null or SoC not initialized"); 81520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("Error : hci, smd initialization Error"); 81620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel retval = -1; 81720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 81820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } else { 81920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("Bluetooth FW and transport layer are initialized"); 8205752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); 8210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 82220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 8230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 8250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_SCO_CFG: 8265752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy 8270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 8290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_ANT_USERIAL_OPEN: 8300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_OPEN"); 8310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel is_ant_req = true; 8320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel goto userial_open; 8330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 8340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 8350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_FM_USERIAL_OPEN: 8360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_OPEN"); 8370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel is_fm_req = true; 8380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel goto userial_open; 8390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 8400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudeluserial_open: 8410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_USERIAL_OPEN: 8420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 84320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 84420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 84520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 84620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 8470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int (*fd_array)[] = (int (*)[]) param; 8480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int idx, fd = -1, fd_filter = -1; 8490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_USERIAL_OPEN"); 8505752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 8510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 8520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_DEFAULT: 8530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 8545752ddcecf884adefc166873565da60e70f59400Thierry Strudel if(bt_hci_init_transport(q->fd) != -1){ 8550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int (*fd_array)[] = (int (*) []) param; 8560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 8575752ddcecf884adefc166873565da60e70f59400Thierry Strudel (*fd_array)[CH_CMD] = q->fd[0]; 8585752ddcecf884adefc166873565da60e70f59400Thierry Strudel (*fd_array)[CH_EVT] = q->fd[0]; 8595752ddcecf884adefc166873565da60e70f59400Thierry Strudel (*fd_array)[CH_ACL_OUT] = q->fd[1]; 8605752ddcecf884adefc166873565da60e70f59400Thierry Strudel (*fd_array)[CH_ACL_IN] = q->fd[1]; 8610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 8630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 8640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 2; 8670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_AR3K: 8700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 8710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 8720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd != -1) { 8730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for (idx=0; idx < CH_MAX; idx++) 8740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (*fd_array)[idx] = fd; 8750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 1; 8760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 8780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 8790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 8820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Vendor Specific Process should happened during userial_open process 8830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel After userial_open, rx read thread is running immediately, 8840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel so it will affect VS event read process. 8850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel */ 8860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(ath3k_init(fd,3000000,115200,NULL,&vnd_userial.termios)<0) 8870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 8880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 8900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 8910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 8920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel wait_for_patch_download(is_ant_req); 8930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 8940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!is_soc_initialized()) { 8950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char* dlnd_inprog = is_ant_req ? "ant" : "bt"; 8960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (property_set("wc_transport.patch_dnld_inprog", dlnd_inprog) < 0) { 8970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Failed to set dnld_inprog %s", __FUNCTION__, dlnd_inprog); 8980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 8990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); 9010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd < 0) { 9020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("userial_vendor_open returns err"); 9030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 9040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 9050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Clock on */ 9080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel userial_clock_operation(fd, USERIAL_OP_CLK_ON); 9090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(strcmp(emb_wp_mode, "true") == 0) { 9110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("ro.bluetooth.wipower", wipower_status, false); 9120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(strcmp(wipower_status, "true") == 0) { 9130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel check_embedded_mode(fd); 9140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 9150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("Wipower not enabled"); 9160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("rome_soc_init is started"); 9190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.soc_initialized", "0"); 9200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef READ_BT_ADDR_FROM_PROP 9210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*Give priority to read BD address from boot property*/ 9220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = FALSE; 9230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (property_get(BLUETOOTH_MAC_ADDR_BOOT_PROPERTY, bd_addr, NULL)) { 9240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("BD address read from Boot property: %s\n", bd_addr); 9250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel tok = strtok(bd_addr, ":"); 9260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel while (tok != NULL) { 9270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("bd add [%d]: %d ", i, strtol(tok, NULL, 16)); 9280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (i>=6) { 9290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("bd property of invalid length"); 9300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = TRUE; 9310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 9320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 93320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (i == 6 && !ignore_boot_prop) { 93420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGV("Valid BD address read from prop"); 9355752ddcecf884adefc166873565da60e70f59400Thierry Strudel memcpy(q->bdaddr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 93620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ignore_boot_prop = FALSE; 93720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } else { 93820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("There are not enough tokens in BD addr"); 9390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = TRUE; 9400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 9410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel local_bd_addr_from_prop[5-i] = strtol(tok, NULL, 16); 9430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel tok = strtok(NULL, ":"); 9440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel i++; 9450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (i == 6 && !ignore_boot_prop) { 9470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("Valid BD address read from prop"); 9480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel memcpy(vnd_local_bd_addr, local_bd_addr_from_prop, sizeof(vnd_local_bd_addr)); 9490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = FALSE; 9500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 9510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("There are not enough tokens in BD addr"); 9520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = TRUE; 9530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 9560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("BD address boot property not set"); 9570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ignore_boot_prop = TRUE; 9580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif //READ_BT_ADDR_FROM_PROP 96048e31bec582e3854b3aaad0ebaaf4ac2ad6a33dbThierry Strudel#ifdef BT_NV_SUPPORT 9610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Always read BD address from NV file */ 9625752ddcecf884adefc166873565da60e70f59400Thierry Strudel if(ignore_boot_prop && !bt_vendor_nv_read(1, q->bdaddr)) 9630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 9640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* Since the BD address is configured in boot time We should not be here */ 9650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("Failed to read BD address. Use the one from bluedroid stack/ftm"); 9660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 96748e31bec582e3854b3aaad0ebaaf4ac2ad6a33dbThierry Strudel#endif //BT_NV_SUPPORT 9685752ddcecf884adefc166873565da60e70f59400Thierry Strudel if(rome_soc_init(fd, (char*)q->bdaddr)<0) { 9690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 9700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 9710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("rome_soc_init is completed"); 9720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.soc_initialized", "1"); 9730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel skip_init = false; 9740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 9770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Failed to set property", __FUNCTION__); 9780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.clean_up","0"); 9810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (retval != -1) { 9820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = start_hci_filter(); 9840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (retval < 0) { 9850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: WCNSS_FILTER wouldn't have started in time\n", __func__); 9860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 9870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 9880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_ant_req) { 9890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: connect to ant channel", __func__); 9905752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 9910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 9930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 9940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 9950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: connect to bt channel", __func__); 9960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 9970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 9980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 9990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd_filter != -1) { 10000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: received the socket fd: %d is_ant_req: %d is_fm_req: %d\n", 10010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel __func__, fd_filter, is_ant_req,is_fm_req); 10020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if((strcmp(emb_wp_mode, "true") == 0) && !is_ant_req && !is_fm_req) { 10030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (chipset_ver >= ROME_VER_3_0) { 10040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /* get rome supported feature request */ 10050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: %x08 %0x", __FUNCTION__,chipset_ver, ROME_VER_3_0); 10060ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel rome_get_addon_feature_list(fd_filter); 10070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (!skip_init) { 10100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*Skip if already sent*/ 10110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel enable_controller_log(fd_filter, (is_ant_req || is_fm_req) ); 10120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel skip_init = true; 10130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for (idx=0; idx < CH_MAX; idx++) 10150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (*fd_array)[idx] = fd_filter; 10160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 1; 10170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 10190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_ant_req) 10200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Unable to connect to ANT Server Socket!!!"); 10210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 10220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Unable to connect to BT Server Socket!!!"); 10230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 10240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 10275752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->soc_type == BT_SOC_ROME) 10280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Failed to initialize ROME Controller!!!"); 10290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 10310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd >= 0) { 10320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel userial_clock_operation(fd, USERIAL_OP_CLK_OFF); 10330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*Close the UART port*/ 10340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel close(fd); 10350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 10380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 10390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 10400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("ro.bluetooth.emb_wp_mode", emb_wp_mode, false); 10410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = start_hci_filter(); 10420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (retval < 0) { 10430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("WCNSS_FILTER wouldn't have started in time\n"); 104469ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel /* 104569ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel Set the following property to -1 so that the SSR cleanup routine 104669ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel can reset SOC. 104769ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel */ 104869ba81cb05c2c2cdb68de73653458367bb342de0Thierry Strudel property_set("wc_transport.hci_filter_status", "-1"); 10490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 10500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 10510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_ant_req) { 10520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: connect to ant channel", __func__); 10535752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->ant_fd = fd_filter = connect_to_local_socket("ant_sock"); 10540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 10560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 10570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 10585752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (is_fm_req && (q->soc_type >=BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED)) { 10590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: connect to fm channel", __func__); 10605752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->fm_fd = fd_filter = connect_to_local_socket("fm_sock"); 10610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 10630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 10640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 10650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: connect to bt channel", __func__); 10660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel vnd_userial.fd = fd_filter = connect_to_local_socket("bt_sock"); 10670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 10680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (fd_filter != -1) { 10700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: received the socket fd: %d \n", 10710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel __func__, fd_filter); 10720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 10730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel for (idx=0; idx < CH_MAX; idx++) { 10740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel (*fd_array)[idx] = fd_filter; 10750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 1; 10770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 10790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 10800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_ant_req) 10810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Unable to connect to ANT Server Socket!!!"); 10820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 10830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 10840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 10850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_fm_req) 10860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Unable to connect to FM Server Socket!!!"); 10870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 10880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 10890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("Unable to connect to BT Server Socket!!!"); 10900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 10910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 10950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 10965752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("Unknown soc_type: 0x%x", q->soc_type); 10970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 10980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 10990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } break; 11000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 11010ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_ANT_USERIAL_CLOSE: 11020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 11030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_ANT_USERIAL_CLOSE"); 110420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel property_set("wc_transport.clean_up","1"); 11055752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->ant_fd != -1) { 110620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("closing ant_fd"); 11075752ddcecf884adefc166873565da60e70f59400Thierry Strudel close(q->ant_fd); 11085752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->ant_fd = -1; 11090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 111120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 11120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 11130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 11140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_FM_USERIAL_CLOSE: 11150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 11160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("bt-vendor : BT_VND_OP_FM_USERIAL_CLOSE"); 11170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_set("wc_transport.clean_up","1"); 11185752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->fm_fd != -1) { 11190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("closing fm_fd"); 11205752ddcecf884adefc166873565da60e70f59400Thierry Strudel close(q->fm_fd); 11215752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->fm_fd = -1; 11220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 112420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 11250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 11260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_USERIAL_CLOSE: 11270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 11285752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGI("bt-vendor : BT_VND_OP_USERIAL_CLOSE soc_type: %d", q->soc_type); 11295752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 11300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 11310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_DEFAULT: 11325752ddcecf884adefc166873565da60e70f59400Thierry Strudel bt_hci_deinit_transport(q->fd); 11330ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 11350ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_AR3K: 11360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 11370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 113820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel property_set("wc_transport.clean_up","1"); 113920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel userial_vendor_close(); 11400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 11435752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("Unknown soc_type: 0x%x", q->soc_type); 11440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 11490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: 11500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 115120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 115220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 115320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 115420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 11550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel uint32_t *timeout_ms = (uint32_t *) param; 11560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel *timeout_ms = 1000; 11570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 11590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 11610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_LPM_SET_MODE: 11625752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->soc_type == BT_SOC_AR3K) { 116320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 116420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 116520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 116620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 11670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel uint8_t *mode = (uint8_t *) param; 11680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 11690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (*mode) { 11700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel lpm_set_ar3k(UPIO_LPM_MODE, UPIO_ASSERT, 0); 11710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 11730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel lpm_set_ar3k(UPIO_LPM_MODE, UPIO_DEASSERT, 0); 11740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11755752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->lpm_cb(BT_VND_OP_RESULT_SUCCESS); 117620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } else { 1177190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel int lpm_result = BT_VND_OP_RESULT_SUCCESS; 1178190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel 1179190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel property_get("persist.service.bdroid.lpmcfg", lpm_config, "all"); 1180190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel ALOGI("%s: property_get: persist.service.bdroid.lpmcfg: %s", 1181190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel __func__, lpm_config); 1182190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel 1183190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel if (!strcmp(lpm_config, "all")) { 1184190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel // respond with success since we want to hold wake lock through LPM 1185190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel lpm_result = BT_VND_OP_RESULT_SUCCESS; 1186190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel } 1187190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel else { 1188190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel lpm_result = BT_VND_OP_RESULT_FAIL; 1189190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel } 1190190a4be3a00ae97925465dccdf68ecf1c066306dThierry Strudel 11915752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->lpm_cb(lpm_result); 11920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 11930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 11940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 119520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_VND_OP_LPM_WAKE_SET_STATE: { 11965752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) { 119720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_CHEROKEE: 119820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_ROME: { 119920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 120020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 120120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 120220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 120320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel uint8_t *state = (uint8_t *) param; 120420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 120520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel BT_VND_LPM_WAKE_ASSERT : BT_VND_LPM_WAKE_DEASSERT; 120620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 120720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (wake_assert == 0) 120820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGV("ASSERT: Waking up BT-Device"); 120920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel else if (wake_assert == 1) 121020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGV("DEASSERT: Allowing BT-Device to Sleep"); 121120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 121220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel#ifdef QCOM_BT_SIBS_ENABLE 121320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("Invoking HCI H4 callback function"); 12145752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->lpm_set_state_cb(wake_assert); 121520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel#endif 12160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 121820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_AR3K: { 121920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (!param) { 122020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("opcode = %d: param is null", opcode_init); 122120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 12220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 122320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel uint8_t *state = (uint8_t *) param; 122420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ 122520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel UPIO_ASSERT : UPIO_DEASSERT; 122620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel lpm_set_ar3k(UPIO_BT_WAKE, wake_assert, 0); 122720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 122820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_SOC_DEFAULT: 122920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 123020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel default: 12315752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("Unknown soc_type: 0x%x", q->soc_type); 123220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 123320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 123420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel } 123520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel break; 123620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel case BT_VND_OP_EPILOG: { 123720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel#if (HW_NEED_END_WITH_HCI_RESET == FALSE) 12385752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 12390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#else 12405752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 12410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 12420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 12430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 12440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 12450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char value[PROPERTY_VALUE_MAX] = {'\0'}; 12460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("wc_transport.hci_filter_status", value, "0"); 12470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(is_soc_initialized()&& (strcmp(value,"1") == 0)) 12480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 124920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel __hw_epilog_process(); 12500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else 12520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 12535752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb->epilog_cb(BT_VND_OP_RESULT_SUCCESS); 12540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12560ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 125820f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel __hw_epilog_process(); 12590ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12600ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12610ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 12620ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12630ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12640ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_VND_OP_GET_LINESPEED: 12650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 12660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = -1; 12670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(!is_soc_initialized()) { 12680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("BT_VND_OP_GET_LINESPEED: error" 12690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel " - transport driver not initialized!"); 12700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 12735752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 12740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 12750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 12760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 3200000; 12770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 12790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = 3000000; 12800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 12820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = userial_vendor_get_baud(); 12830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 12860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 12880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 128920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelout: 129020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGV("--%s", __FUNCTION__); 12910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return retval; 12920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 12930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 129420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic void ssr_cleanup(int reason) 129520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel{ 129620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel int pwr_state = BT_VND_PWR_OFF; 12970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret; 12980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel unsigned char trig_ssr = 0xEE; 12991414527307ab6aae2c497b3d2122278cb9ca1aa1Frank Barchard#ifndef ENABLE_ANT 13001414527307ab6aae2c497b3d2122278cb9ca1aa1Frank Barchard (void)reason; // unused 13011414527307ab6aae2c497b3d2122278cb9ca1aa1Frank Barchard#endif 13020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 130320f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("++%s", __FUNCTION__); 130420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 13055752ddcecf884adefc166873565da60e70f59400Thierry Strudel pthread_mutex_lock(&q_lock); 13065752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (!q) { 13075752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("ssr_cleanup called with NULL context"); 13085752ddcecf884adefc166873565da60e70f59400Thierry Strudel goto out; 13095752ddcecf884adefc166873565da60e70f59400Thierry Strudel } 131020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel if (property_set("wc_transport.patch_dnld_inprog", "null") < 0) { 131120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGE("Failed to set property"); 13120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13145752ddcecf884adefc166873565da60e70f59400Thierry Strudel if (q->soc_type >= BT_SOC_ROME && q->soc_type < BT_SOC_RESERVED) { 131520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel#ifdef ENABLE_ANT 131620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /*Indicate to filter by sending special byte */ 13170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (reason == CMD_TIMEOUT) { 13180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel trig_ssr = 0xEE; 13190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = write (vnd_userial.fd, &trig_ssr, 1); 132020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("Trig_ssr is being sent to BT socket, ret %d err %s", 132120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ret, strerror(errno)); 13220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13230ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (is_debug_force_special_bytes()) { 132420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /* 132520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel * Then we should send special byte to crash SOC in 132620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel * WCNSS_Filter, so we do not need to power off UART here. 132720f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel */ 132841464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudel goto out; 13290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 133120f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 133220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /* Close both ANT channel */ 1333d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanus op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL); 13340ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 133520f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel /* Close both BT channel */ 1336d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanus op(BT_VND_OP_USERIAL_CLOSE, NULL); 13370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef FM_OVER_UART 1339d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanus op(BT_VND_OP_FM_USERIAL_CLOSE, NULL); 13400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 13410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*CTRL OFF twice to make sure hw 13420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel * turns off*/ 13430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef ENABLE_ANT 1344d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanus op(BT_VND_OP_POWER_CTRL, &pwr_state); 13450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif 13460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel /*Generally switching of chip should be enough*/ 1348d659daacec1c7697ad086dee638759c8991ebe45Mark Urbanus op(BT_VND_OP_POWER_CTRL, &pwr_state); 134920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 135041464994bbeb484687aa81ac08b72b8e51d37b11Thierry Strudelout: 13515752ddcecf884adefc166873565da60e70f59400Thierry Strudel pthread_mutex_unlock(&q_lock); 135220f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel ALOGI("--%s", __FUNCTION__); 13530ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 13540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13550ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/** Closes the interface */ 135620f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudelstatic void cleanup(void) 13570ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel{ 13580ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("cleanup"); 135920f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel 136020f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel pthread_mutex_lock(&q_lock); 13615752ddcecf884adefc166873565da60e70f59400Thierry Strudel q->cb = NULL; 13625752ddcecf884adefc166873565da60e70f59400Thierry Strudel free(q); 13635752ddcecf884adefc166873565da60e70f59400Thierry Strudel q = NULL; 136420f50076d30e7d1c55c2d8206e01534f2df9112bThierry Strudel pthread_mutex_unlock(&q_lock); 13650ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13660ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#ifdef WIFI_BT_STATUS_SYNC 13670ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel isInit = 0; 13680ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel#endif /* WIFI_BT_STATUS_SYNC */ 13690ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 13700ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13710ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel/* Check for one of the cients ANT/BT patch download is already in 13720ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel** progress if yes wait till complete 13730ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel*/ 13740ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelvoid wait_for_patch_download(bool is_ant_req) { 13750ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s:", __FUNCTION__); 13760ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 13770ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel while (1) { 13780ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 13790ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13800ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(is_ant_req && !(strcmp(inProgress,"bt"))) { 13810ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //ANT request, wait for BT to finish 13820ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(50000); 13830ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13840ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else if(!is_ant_req && !(strcmp(inProgress,"ant"))) { 13850ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel //BT request, wait for ANT to finish 13860ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel usleep(50000); 13870ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13880ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel else { 13890ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: patch download completed", __FUNCTION__); 13900ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 13910ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13920ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 13930ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 13940ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13950ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelbool is_download_progress () { 13960ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char inProgress[PROPERTY_VALUE_MAX] = {'\0'}; 13970ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool retval = false; 13980ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 13990ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s:", __FUNCTION__); 14000ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14015752ddcecf884adefc166873565da60e70f59400Thierry Strudel if ((q->soc_type = get_bt_soc_type()) < 0) { 14020ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGE("%s: Failed to detect BT SOC Type", __FUNCTION__); 14030ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return -1; 14040ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 14050ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14065752ddcecf884adefc166873565da60e70f59400Thierry Strudel switch(q->soc_type) 14070ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel { 14080ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_ROME: 14090ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: ROME case", __func__); 14100ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel property_get("wc_transport.patch_dnld_inprog", inProgress, "null"); 14110ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if(strcmp(inProgress,"null") == 0) { 14120ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = false; 14130ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } else { 14140ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel retval = true; 14150ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 14160ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 14170ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_CHEROKEE: 14180ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGI("%s: CHEROKEE case", __func__); 14190ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 14200ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel case BT_SOC_DEFAULT: 14210ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 14220ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel default: 14235752ddcecf884adefc166873565da60e70f59400Thierry Strudel ALOGE("Unknown btSocType: 0x%x", q->soc_type); 14240ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel break; 14250ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 14260ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return retval; 14270ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 14280ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14290ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelstatic bool is_debug_force_special_bytes() { 14300ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel int ret = 0; 14310ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel char value[PROPERTY_VALUE_MAX] = {'\0'}; 14320ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel bool enabled = false; 1433bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel#ifdef ENABLE_DBG_FLAGS 1434bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel enabled = true; 1435bc37ff26d048752c4ef50c9dd28945aa8bfe6f5aThierry Strudel#endif 14360ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14370ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ret = property_get("wc_transport.force_special_byte", value, NULL); 14380ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14390ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel if (ret) { 14400ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel enabled = (strcmp(value, "false") ==0) ? false : true; 14410ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel ALOGV("%s: wc_transport.force_special_byte: %s, enabled: %d ", 14420ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel __func__, value, enabled); 14430ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel } 14440ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14450ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel return enabled; 14460ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel} 14470ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel 14480ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel// Entry point of DLib 14490ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudelconst bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = { 14500ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel sizeof(bt_vendor_interface_t), 14510ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel init, 14520ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel op, 14531414527307ab6aae2c497b3d2122278cb9ca1aa1Frank Barchard cleanup 14540ebd0bab066cd86d7a19f4646e0686dae885004eThierry Strudel}; 1455