diff --git a/Android.mk b/Android.mk index 0c77a12425351e85f23144c45314866fa3b3ac76..03e16f081db31ac6b5571b7d5105d55bbab0952f 100644 --- a/Android.mk +++ b/Android.mk @@ -32,6 +32,9 @@ include $(LOCAL_PATH)/fm_hci/Android.mk LOCAL_PATH := $(LOCAL_DIR_PATH) include $(LOCAL_PATH)/helium/Android.mk +LOCAL_PATH := $(LOCAL_DIR_PATH) +include $(LOCAL_PATH)/fmhalService/Android.mk + #endif # is-vendor-board-platform #endif # BOARD_HAVE_QCOM_FM #endif # Not (TARGET_USES_AOSP) diff --git a/fm_hci/fm_hci.c b/fm_hci/fm_hci.c index f3554f27c400874f99a56becbfbc8229259619f5..0cf2de83861fa3b3237125301654179eac3b7110 100644 --- a/fm_hci/fm_hci.c +++ b/fm_hci/fm_hci.c @@ -37,20 +37,34 @@ #include "userial.h" #include "fm_hci.h" #include "wcnss_hci.h" +#include <stdlib.h> #include <dlfcn.h> #include <sys/eventfd.h> #include <errno.h> #include <string.h> +#include <sys/socket.h> +#include <cutils/sockets.h> +#include <pthread.h> +#include <sys/select.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/un.h> +#include <cutils/properties.h> int fm_fd; +static int fm_hal_fd =0; fm_hal_cb *hal_cb; +#define FM_VND_SERVICE_START "wc_transport.start_fmhci" +#define WAIT_TIMEOUT 200000 /* 200*1000us */ + // The set of events one can send to the userial read thread. // Note that the values must be >= 0x8000000000000000 to guarantee delivery // of the message (see eventfd(2) for details on blocking behaviour). enum { USERIAL_RX_EXIT = 0x8000000000000000ULL }; +bt_vendor_interface_t *fm_vnd_if = NULL; void event_notification(uint16_t event) { @@ -60,8 +74,6 @@ void event_notification(uint16_t event) ALOGI("%s: Notifying worker thread with event: %d", __func__, event); pthread_mutex_unlock(&fmHCIControlBlock.event_lock); } - -bt_vendor_interface_t *fm_vnd_if = NULL; void init_vnd_if() { void *dlhandle; @@ -254,7 +266,7 @@ static int read_fm_event(int fd, FM_EVT_HDR *pbuf, int len) ALOGI("%s: FM H/w Err Event Recvd. Event Code: 0x%2x", __func__, pbuf->evt_code); lib_running =0; // commented till bt vendor include added - // fm_vnd_if->ssr_cleanup(); + // fm_vnd_if->ssr_cleanup(0x22); } else { ALOGI("%s: Not CS/CC Event: Recvd. Event Code: 0x%2x", __func__, pbuf->evt_code); evt_type = -1; @@ -289,13 +301,11 @@ static int read_fm_event(int fd, FM_EVT_HDR *pbuf, int len) ret = ret - (evt_len + 3); ALOGD("%s: Length of available bytes @ HCI Layer: %d", __func__, ret); - if (ret > 0) { ALOGD("%s: Remaining bytes of event/data: %d", __func__, ret); pbuf = (FM_EVT_HDR *)&pbuf->cmd_params[evt_len]; ALOGD("%s: Protocol byte of next packet: 0x%2x", __func__, pbuf[0]); } - } } //end of processing the event @@ -330,6 +340,28 @@ static void *userial_read_thread(void *arg) return arg; } +int connect_to_local_fmsocket(char* name) { + socklen_t len; int sk = -1; + + ALOGE("%s: ACCEPT ", __func__); + sk = socket(AF_LOCAL, SOCK_STREAM, 0); + if (sk < 0) { + ALOGE("Socket creation failure"); + return -1; + } + + if(socket_local_client_connect(sk, name, + ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) + { + ALOGE("failed to connect (%s)", strerror(errno)); + close(sk); + sk = -1; + } else { + ALOGE("%s: Connection succeeded\n", __func__); + } + return sk; +} + /* * Reads the FM-CMDs from the TX_Q and sends it down to WCNSS Filter * Reads events sent by the WCNSS Filter and copies onto RX_Q @@ -360,6 +392,50 @@ static void* fmHCITask(void *arg) return arg; } +void stop_fmhal_service() { + char value[PROPERTY_VALUE_MAX] = {'\0'}; + ALOGI("%s: Entry ", __func__); + property_get(FM_VND_SERVICE_START, value, "false"); + if (strcmp(value, "false") == 0) { + ALOGI("%s: fmhal service has been stopped already", __func__); +// return; + } + close(fm_hal_fd); + fm_hal_fd = -1; + property_set(FM_VND_SERVICE_START, "false"); + property_set("wc_transport.fm_service_status", "0"); + ALOGI("%s: Exit ", __func__); +} + +void start_fmhal_service() { + ALOGI("%s: Entry ", __func__); + int i, init_success = 0; + char value[PROPERTY_VALUE_MAX] = {'\0'}; + + property_get(FM_VND_SERVICE_START, value, false); + + if (strcmp(value, "true") == 0) { + ALOGI("%s: hci_filter has been started already", __func__); + return; + } + // property_set("wc_transport.fm_service_status", "0"); + property_set(FM_VND_SERVICE_START, "true"); + ALOGI("%s: %s set to true ", __func__, FM_VND_SERVICE_START ); + for(i=0; i<45; i++) { + property_get("wc_transport.fm_service_status", value, "0"); + if (strcmp(value, "1") == 0) { + ALOGI("%s: wc_transport.fm_service_status set to %s", __func__,value); + init_success = 1; + break; + } else { + usleep(WAIT_TIMEOUT); + } + } + ALOGI("start_fmhal_service status:%d after %f seconds \n", init_success, 0.2*i); + + ALOGI("%s: Exit ", __func__); +} + int fm_hci_init(fm_hal_cb *p_cb) { pthread_attr_t thread_attr; @@ -367,13 +443,17 @@ int fm_hci_init(fm_hal_cb *p_cb) int policy, result, hci_type; ALOGI("FM-HCI: init"); - + start_fmhal_service(); /* Save the FM-HAL event notofication callback func. */ hal_cb = p_cb; - - ALOGI("FM-HCI: Loading the WCNSS HAL library..."); - init_vnd_if(); - + fm_hal_fd = connect_to_local_fmsocket("fmhal_sock"); + if(fm_hal_fd != -1) + { + ALOGI("FM hal service socket connect success.."); + } + ALOGI("fm_hal_fd = %d", fm_hal_fd); + //if(fm_hal_fd == -1) + // return FM_HC_STATUS_FAIL; ALOGI("%s: Initializing FM-HCI layer...", __func__); lib_running = 1; ready_events = 0; @@ -413,23 +493,61 @@ int fm_hci_init(fm_hal_cb *p_cb) } else ALOGI("FM-HCI: Failed to get the Scheduling parameters!!!"); + ALOGI("FM-HCI: Loading the WCNSS HAL library..."); + init_vnd_if(); return FM_HC_STATUS_SUCCESS; } -void fm_power(fm_power_state state) +int fm_power(fm_power_state state) { - int val; - - if (state) { - ALOGI("FM-HCI: %s: Turning FM ON", __func__); - val = state; - fm_vnd_if->op(FM_VND_OP_POWER_CTRL, &val); - } else { - ALOGI("FM-HCI: %s: Turning FM OFF", __func__); - val = state; - fm_vnd_if->op(FM_VND_OP_POWER_CTRL, &val); + int i,opcode,ret; + int init_success = 0; + char value[PROPERTY_VALUE_MAX] = {'\0'}; + if (fm_hal_fd) + { + if (state) + opcode = 2; + else { + opcode = 1; + } + ALOGI("%s:opcode: %x", LOG_TAG, opcode); + ret = write(fm_hal_fd,&opcode, 1); + if (ret < 0) + { + ALOGE("failed to write fm hal socket"); + } + } + else { + ALOGE("Connect to socket failed .."); + ret = -1; + } + if(state == FM_RADIO_DISABLE) { + for (i=0; i<10; i++) { + property_get("wc_transport.fm_power_status", value, "0"); + if (strcmp(value, "0") == 0) { + init_success = 1; + break; + } else { + usleep(WAIT_TIMEOUT); + } + } + ALOGI("fm power OFF status:%d after %f seconds \n", init_success, 0.2*i); + stop_fmhal_service(); + } + if (state == FM_RADIO_ENABLE) { + for (i=0; i<10; i++) { + property_get("wc_transport.fm_power_status", value, "0"); + if (strcmp(value, "1") == 0) { + init_success = 1; + break; + } else { + usleep(WAIT_TIMEOUT); + } + } + ALOGI("fm power ON status:%d after %f seconds \n", init_success, 0.2*i); } + return ret; } #define CH_MAX 3 diff --git a/fm_hci/fm_hci.h b/fm_hci/fm_hci.h index 2d5e4a157c1e90ea20b12d2e16596ce4f6466494..cfacb8433a8cd2919d47578ac0500c98cbe4741f 100644 --- a/fm_hci/fm_hci.h +++ b/fm_hci/fm_hci.h @@ -100,7 +100,7 @@ typedef struct hdr int transmit(FM_HDR *pbuf); int fm_hci_init(fm_hal_cb *); -void fm_power(fm_power_state state); +int fm_power(fm_power_state state); int open_serial_port(void); void fm_userial_close(void); diff --git a/fmhalService/Android.mk b/fmhalService/Android.mk new file mode 100644 index 0000000000000000000000000000000000000000..ad67eb9017593e200d261e8630748f33058475c5 --- /dev/null +++ b/fmhalService/Android.mk @@ -0,0 +1,37 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +# Setup bdroid local make variables for handling configuration +ifneq ($(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR),) + bdroid_C_INCLUDES := $(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR) + bdroid_CFLAGS += -DHAS_BDROID_BUILDCFG +else + bdroid_C_INCLUDES := + bdroid_CFLAGS += -DHAS_NO_BDROID_BUILDCFG +endif + +BDROID_DIR:= system/bt + +LOCAL_CFLAGS += $(bdroid_CFLAGS) + +LOCAL_SRC_FILES := \ + main.c + +LOCAL_SHARED_LIBRARIES := \ + libdl \ + libcutils + +LOCAL_CFLAGS := -Wno-unused-parameter + +LOCAL_C_INCLUDES += \ + $(BDROID_DIR)/hci/include \ + $(BDROID_DIR)/stack/include \ + $(BDROID_DIR)/osi/include \ + $(LOCAL_PATH)/../helium \ + $(LOCAL_PATH)/../fm_hci + +LOCAL_MODULE := fmhal_service +LOCAL_MODULE_TAGS := optional + +include $(BUILD_EXECUTABLE) diff --git a/fmhalService/main.c b/fmhalService/main.c new file mode 100644 index 0000000000000000000000000000000000000000..558f681539f4cd4ca3dcbf465413123019e55147 --- /dev/null +++ b/fmhalService/main.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * FMhal service used to access RFKILL + +**/ + +#include <cutils/log.h> +#include <sys/socket.h> +#include <cutils/sockets.h> +#include <pthread.h> +#include <sys/select.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <termios.h> +#include <fcntl.h> +#include <sys/un.h> +#include <sys/eventfd.h> +#include <errno.h> +#include <string.h> + +#include <cutils/properties.h> +#include "private/android_filesystem_config.h" + + +//#include "bt_hci_bdroid.h" +#include "bt_vendor_lib.h" +#include "fm_hci.h" +#include "wcnss_fmhci.h" +#include <dlfcn.h> + + +#define LOG_TAG "FMHalService" + +#define FM_HAL_SOCK "fmhal_sock" + + +#define BT_SSR_TRIGGERED 0xee + +#define FM_POWER_OFF 0x01 +#define FM_POWER_ON 0x02 +#define FM_USERIAL_OPEN 0x03 +#define FM_USERIAL_CLOSE 0x04 + +#define FM_CMD_PACKET_TYPE 0x11 +#define FM_EVT_PACKET_TYPE 0x14 + +#ifndef BLUETOOTH_UID +#define BLUETOOTH_UID 1002 +#endif +#ifndef SYSTEM_UID +#define SYSTEM_UID 1000 +#endif + +#ifndef ROOT_UID +#define ROOT_UID 0 +#endif + +pthread_mutex_t signal_mutex; + +bt_vendor_interface_t *fm_if = NULL; +int remote_fm_hal_fd; + +int do_write(int fd, unsigned char *buf,int len); + +unsigned char reset_cmpl[] = {0x04, 0x0e, 0x04, 0x01,0x03, 0x0c, 0x00}; + +static int extract_uid(int uuid) +{ + int userid; + int appid; + + appid = userid = uuid % AID_USER; + if (userid > BLUETOOTH_UID) + { + appid = userid % AID_APP; + } + ALOGD("%s appid = %d",__func__,appid); + return appid; +} + void service_cleanup() +{ + char ref_count[PROPERTY_VALUE_MAX]; + char cleanup[PROPERTY_VALUE_MAX]; + int ref_val,clean; + + ALOGE("Service is stopped "); + property_get("wc_transport.clean_up", cleanup, "0"); + property_set("wc_transport.fm_service_status", "0"); + property_set("wc_transport.start_fmhci", "0"); + property_set("wc_transport.fm_power_status", "0"); + clean = atoi(cleanup); + ALOGE("clean Value = %d",clean); +} + +static int establish_fm_remote_socket(char *name) +{ + int fd = -1; + struct sockaddr_un client_address; + socklen_t clen; + int sock_id, ret; + struct ucred creds; + int c_uid; + ALOGI("%s(%s) Entry ", __func__, name); + + sock_id = socket(AF_LOCAL, SOCK_STREAM, 0); + if (sock_id < 0) { + ALOGE("%s: server Socket creation failure", __func__); + return fd; + } + + ALOGI("convert name to android abstract name:%s %d", name, sock_id); + if (socket_local_server_bind(sock_id, + name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0) { + if (listen(sock_id, 5) == 0) { + ALOGI("listen to local socket:%s, fd:%d", name, sock_id); + } else { + ALOGE("listen to local socket:failed"); + close(sock_id); + return fd; + } + } else { + close(sock_id); + ALOGE("%s: server bind failed for socket : %s", __func__, name); + return fd; + } + + clen = sizeof(client_address); + /*Indicate that, server is ready to accept*/ + property_set("wc_transport.fm_service_status", "1"); + ALOGI("%s: wc_transport.fm_service_status set to 1 ", __func__); + ALOGI("%s: before accept_server_socket", name); + fd = accept(sock_id, (struct sockaddr *)&client_address, &clen); + if (fd > 0) { + ALOGI("%s accepted fd:%d for server fd:%d", name, fd, sock_id); + close(sock_id); + + memset(&creds, 0, sizeof(creds)); + socklen_t szCreds = sizeof(creds); + ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); + if (ret < 0) { + ALOGE("%s: error getting remote socket creds: %d\n", __func__, ret); + close(fd); + return -1; + } + c_uid = creds.uid; + if (c_uid > BLUETOOTH_UID) + c_uid = extract_uid(creds.uid); + if (c_uid != BLUETOOTH_UID && c_uid != SYSTEM_UID + && c_uid != ROOT_UID) { + ALOGE("%s: client doesn't have required credentials", __func__); + ALOGE("<%s req> client uid: %d", name, creds.uid); + close(fd); + return -1; + } + + ALOGI("%s: Remote socket credentials: %d\n", __func__, creds.uid); + return fd; + } else { + ALOGE("BTC accept failed fd:%d sock d:%d error %s", fd, sock_id, strerror(errno)); + close(sock_id); + return fd; + } + + close(sock_id); + return fd; +} + + +int handle_fmcommand_writes(int fd) { + ALOGI("%s: ", __func__); + unsigned char first_byte; + int retval,val; + int fd_array[CH_MAX]; + + ALOGE("%s: FMHAL: read 1st byte to determine the power on/off ", __func__); + + retval = read (fd, &first_byte, 1); + if (retval < 0) { + ALOGE("%s:read returns err: %d\n", __func__,retval); + return -1; + } + if (retval == 0) { + ALOGE("%s: This indicates the close of other end", __func__); + return -99; + } + + ALOGE("%s: FM command type: 0x%x", __func__, first_byte); + switch(first_byte) { + case FM_POWER_OFF: + ALOGE("%s: Received power off command from FM stack: %d", __func__, first_byte); + val = 0; + retval = fm_if->op(BT_VND_OP_POWER_CTRL, &val); + if (retval < 0) + { + ALOGE("Failed to turn off power from bt vendor interface"); + // return -1; + } + else { + property_set("wc_transport.fm_power_status", "0"); + retval = -99; + } + break; + + case FM_POWER_ON: + ALOGE("%s: Received power ON command from FM stack: %d", __func__, first_byte); + val = 1; + retval =fm_if->op(FM_VND_OP_POWER_CTRL, &val); + if (retval < 0) + { + ALOGE("Failed to turn on power from bt vendor interface"); + } + else + property_set("wc_transport.fm_power_status", "1"); + break; + default: + ALOGE("%s: Unexpected data format!!",__func__); + retval = -1; + } + return retval; +} + + +int do_read(int fd, unsigned char* buf, size_t len) { + int bytes_left, bytes_read = 0, read_offset; + + bytes_left = len; + read_offset = 0; + + do { + bytes_read = read(fd, buf+read_offset, bytes_left); + if (bytes_read < 0) { + ALOGE("%s: Read error: %d (%s)", __func__, bytes_left, strerror(errno)); + return -1; + } else if (bytes_read == 0) { + ALOGE("%s: read returned 0, err = %s, read bytes: %d, expected: %d", + __func__, strerror(errno), (len-bytes_left), len); + return (len-bytes_left); + } + else { + if (bytes_read < bytes_left) { + ALOGV("Still there are %d bytes to read", bytes_left-bytes_read); + bytes_left = bytes_left-bytes_read; + read_offset = read_offset+bytes_read; + } else { + ALOGV("%s: done with read",__func__); + break; + } + } + }while(1); + return len; +} + +int do_write(int fd, unsigned char *buf,int len) +{ + int ret = 0; + int write_offset = 0; + int write_len = len; + do { + ret = write(fd, buf+write_offset, write_len); + if (ret < 0) + { + ALOGE("%s: write failed ret = %d err = %s",__func__,ret,strerror(errno)); + return -1; + + } else if (ret == 0) { + ALOGE("%s: Write returned 0, err = %s, Written bytes: %d, expected: %d", + __func__, strerror(errno), (len-write_len), len); + return (len-write_len); + + } else { + if (ret < write_len) + { + ALOGD("%s, Write pending,do write ret = %d err = %s",__func__,ret, + strerror(errno)); + write_len = write_len - ret; + write_offset = ret; + } else if (ret > write_len) { + ALOGE("%s: FATAL wrote more than expected: written bytes: %d expected: %d", + __func__, write_len, ret); + break; + } else { + ALOGV("Write successful"); + break; + } + } + } while(1); + return len; +} + +void vnd_load_if() +{ + void *dlhandle; + unsigned char bdaddr[] = {0xaa, 0xbb, 0xcc, 0x11, 0x22, 0x33}; + + dlhandle = dlopen("libbt-vendor.so", RTLD_NOW); + if (!dlhandle) + { + ALOGE("!!! Failed to load libbt-vendor.so !!!"); + return; + } + + fm_if = (bt_vendor_interface_t *) dlsym(dlhandle, "BLUETOOTH_VENDOR_LIB_INTERFACE"); + if (!fm_if) + { + ALOGE("!!! Failed to get bt vendor interface !!!"); + return; + } + + ALOGI("FM-HCI: Registering the WCNSS HAL library by passing CBs and BD addr."); + fm_if->init(&fmhci_vendor_callbacks, bdaddr); +} + + +int main() { + fd_set client_fds; + int retval, n; + + ALOGI("%s: Entry ", __func__); + ALOGI("FM HAL SERVICE: Loading the WCNSS HAL library..."); + vnd_load_if(); + ALOGI("create socket"); + remote_fm_hal_fd = establish_fm_remote_socket(FM_HAL_SOCK); + if (remote_fm_hal_fd < 0) { + ALOGE("%s: invalid remote socket", __func__); + return -1; + } + + FD_ZERO(&client_fds); + FD_SET(remote_fm_hal_fd, &client_fds); + + do { + ALOGI("%s: Step 1-FM-HAL SERVICE: Waiting for FM HAL cmd ", __func__); + n = select(remote_fm_hal_fd+1, &client_fds, NULL, NULL, NULL); + if(n < 0){ + ALOGE("Select: failed: %s", strerror(errno)); + break; + } + ALOGI("%s: Step 2-FM-HAL SERVICE: FM POWER CMD available for processing...\n", __func__); + if (FD_ISSET(remote_fm_hal_fd, &client_fds)) { + retval = handle_fmcommand_writes(remote_fm_hal_fd); + ALOGI("%s: handle_fmcommand_writes . %d", __func__, retval); + if(retval < 0) { + if (retval == -99) { + ALOGI("%s:End of wait loop", __func__); + break; + } + ALOGI("%s: handle_fmcommand_writes returns: %d: ", __func__, retval); + // break; + } + } + } while(1); + + service_cleanup(); + ALOGI("%s: FM turned off or power off failed .service kill itself", __func__); + close(remote_fm_hal_fd); + remote_fm_hal_fd = 0; + + ALOGI("%s: Exit: %d", __func__, retval); + return retval; +} + diff --git a/fmhalService/wcnss_fmhci.h b/fmhalService/wcnss_fmhci.h new file mode 100644 index 0000000000000000000000000000000000000000..22029bf0a092a468a7cdc4fc2080ae2b9e88656c --- /dev/null +++ b/fmhalService/wcnss_fmhci.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __WCNSS_FMHCI__ +#define __WCNSS_FMHCI__ +static void vendor_fwcfg_cb(bt_vendor_op_result_t result) { +} + +static void vendor_scocfg_cb(bt_vendor_op_result_t result) { +} + +static void vendor_lpm_vnd_cb(bt_vendor_op_result_t result) { +} + +static void sco_audiostate_cb(bt_vendor_op_result_t result) { +} + +static void* vendor_alloc(int size) { + return NULL; +} + +static void vendor_dealloc(void *p_buf) { +} + +static uint8_t vendor_xmit_cb(uint16_t opcode, void *p_buf, tINT_CMD_CBACK p_cback) { + return 0; +} + +static void vendor_epilog_cb(bt_vendor_op_result_t result) { +} + + +static const bt_vendor_callbacks_t fmhci_vendor_callbacks = { + sizeof(fmhci_vendor_callbacks), + vendor_fwcfg_cb, + vendor_scocfg_cb, + vendor_lpm_vnd_cb, + sco_audiostate_cb, + vendor_alloc, + vendor_dealloc, + vendor_xmit_cb, + vendor_epilog_cb +}; +#endif diff --git a/helium/radio-helium.h b/helium/radio-helium.h index 05fc309e16fc67223cab7818283eba5aac30f429..989bb559e5e14f69f274726d963c82a026963d57 100644 --- a/helium/radio-helium.h +++ b/helium/radio-helium.h @@ -140,6 +140,7 @@ pthread_mutex_t fm_hal; /* HCI timeouts */ #define RADIO_HCI_TIMEOUT (10000) /* 10 seconds */ +#define ECC_EVENT_BUFSIZE 12 typedef enum { ASSOCIATE_JVM, DISASSOCIATE_JVM diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c index 2a29f64d64801d75d73e087d327a96c121d5b656..5437bad9a587292bc3e99fe0e761277cac2f0eae 100644 --- a/helium/radio_helium_hal.c +++ b/helium/radio_helium_hal.c @@ -105,6 +105,7 @@ static void hci_cc_conf_rsp(char *ev_rsp) static void hci_cc_fm_disable_rsp(char *ev_buff) { char status; + int ret; if (ev_buff == NULL) { ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__); @@ -119,7 +120,10 @@ static void hci_cc_fm_disable_rsp(char *ev_buff) jni_cb->disabled_cb(); jni_cb->thread_evt_cb(1); //close the userial port and power off the chip - ALOGE("%s:calling fm userial close\n", LOG_TAG ); + ret = fm_power(FM_RADIO_DISABLE); + ALOGI("fm power off status = %d", ret); + ALOGE("%s:calling fm userial close\n", LOG_TAG ); + // sleep(1); fm_userial_close(); // fm_power(FM_RADIO_DISABLE); } @@ -1105,7 +1109,7 @@ int hal_init( fm_vendor_callbacks_t *p_cb) ret = fm_hci_init(&hal_cb); ALOGE("%s:%s: Turning FM ON...", LOG_TAG, __func__); - fm_power(FM_RADIO_ENABLE); + ret = fm_power(FM_RADIO_ENABLE); ALOGE("%s:%s: Firmware download and HCI Initialization in-progress...", LOG_TAG, __func__); /* TODO : Start the preload timer */