diff options
author | Khurshid <beenish.khurshid@thisisant.com> | 2013-10-01 16:45:34 -0600 |
---|---|---|
committer | Khurshid <beenish.khurshid@thisisant.com> | 2013-10-01 16:45:34 -0600 |
commit | 4d09cf1ee4023c5562a4d3a690d9e8bc24cde4a6 (patch) | |
tree | f57646e4f4d055e93e8830f29e7348eda892aa34 | |
parent | e1e6966c77655c64f089c5b4a3c49912e39f8257 (diff) | |
download | android_external_ant-wireless_ant_native-4d09cf1ee4023c5562a4d3a690d9e8bc24cde4a6.tar.gz android_external_ant-wireless_ant_native-4d09cf1ee4023c5562a4d3a690d9e8bc24cde4a6.tar.bz2 android_external_ant-wireless_ant_native-4d09cf1ee4023c5562a4d3a690d9e8bc24cde4a6.zip |
Android_System_ANT-HAL_1-6-2
-rw-r--r-- | src/common/inc/ant_version.h | 2 | ||||
-rw-r--r-- | src/vfs/ant_native_chardev.c | 57 | ||||
-rw-r--r-- | src/vfs/ant_rx_chardev.c | 78 | ||||
-rw-r--r-- | src/vfs/inc/ant_hci_defines.h | 53 | ||||
-rw-r--r-- | src/vfs/inc/ant_rx_chardev.h | 4 | ||||
-rw-r--r-- | src/vfs/prerelease/ant_driver_defines.h | 13 | ||||
-rw-r--r-- | src/vfs/ste/cg29xx/ant_driver_defines.h | 13 |
7 files changed, 161 insertions, 59 deletions
diff --git a/src/common/inc/ant_version.h b/src/common/inc/ant_version.h index 0b8988b..21f3660 100644 --- a/src/common/inc/ant_version.h +++ b/src/common/inc/ant_version.h @@ -21,7 +21,7 @@ #define LIBANT_STACK_MAJOR "1"
#define LIBANT_STACK_MINOR "6"
-#define LIBANT_STACK_INCRE "1"
+#define LIBANT_STACK_INCRE "2"
#endif // __ANT_VERSION_H
diff --git a/src/vfs/ant_native_chardev.c b/src/vfs/ant_native_chardev.c index df209c2..2b49a8c 100644 --- a/src/vfs/ant_native_chardev.c +++ b/src/vfs/ant_native_chardev.c @@ -30,6 +30,9 @@ #include <fcntl.h> /* for open() */ #include <linux/ioctl.h> /* For hard reset */ #include <pthread.h> +#include <stdint.h> /* for uint64_t */ +#include <sys/eventfd.h> /* For eventfd() */ +#include <unistd.h> /* for read(), write(), and close() */ #include "ant_types.h" #include "ant_native.h" @@ -37,7 +40,7 @@ #include "antradio_power.h" #include "ant_rx_chardev.h" -#include "ant_driver_defines.h" +#include "ant_hci_defines.h" #include "ant_log.h" #if ANT_HCI_SIZE_SIZE > 1 @@ -58,6 +61,8 @@ static pthread_mutex_t stFlowControlLock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t stFlowControlCond = PTHREAD_COND_INITIALIZER; ANTNativeANTStateCb g_fnStateCallback; +static const uint64_t EVENT_FD_PLUS_ONE = 1L; + static void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName); //////////////////////////////////////////////////////////////////// @@ -69,13 +74,14 @@ static void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcChar // - // // Returns: -// ANT_STATUS_SUCCESS +// ANT_STATUS_SUCCESS if intialize completed, else ANT_STATUS_FAILED // // Psuedocode: /* Set variables to defaults Initialise each supported path to chip -RESULT = ANT_STATUS_SUCCESS +Setup eventfd object. +RESULT = ANT_STATUS_SUCCESS if no problems else ANT_STATUS_FAILED */ //////////////////////////////////////////////////////////////////// ANTStatus ant_init(void) @@ -96,7 +102,16 @@ ANTStatus ant_init(void) ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME); #endif // Separate data/command paths - status = ANT_STATUS_SUCCESS; + // Make the eventfd. Want it non blocking so that we can easily reset it by reading. + stRxThreadInfo.iRxShutdownEventFd = eventfd(0, EFD_NONBLOCK); + + // Check for error case + if(stRxThreadInfo.iRxShutdownEventFd == -1) + { + ANT_ERROR("ANT init failed. Could not create event fd. Reason: %s", strerror(errno)); + } else { + status = ANT_STATUS_SUCCESS; + } ANT_FUNC_END(); return status; @@ -105,7 +120,7 @@ ANTStatus ant_init(void) //////////////////////////////////////////////////////////////////// // ant_deinit // -// Doesn't actually do anything. +// clean up eventfd object // // Parameters: // - @@ -123,7 +138,12 @@ ANTStatus ant_deinit(void) ANTStatus result_status = ANT_STATUS_FAILED; ANT_FUNC_START(); - result_status = ANT_STATUS_SUCCESS; + if(close(stRxThreadInfo.iRxShutdownEventFd) < 0) + { + ANT_ERROR("Could not close eventfd in deinit. Reason: %s", strerror(errno)); + } else { + result_status = ANT_STATUS_SUCCESS; + } ANT_FUNC_END(); return result_status; @@ -838,6 +858,16 @@ int ant_enable(void) ant_channel_type eChannel; ANT_FUNC_START(); + // Reset the shutdown signal. + uint64_t counter; + ssize_t result = read(stRxThreadInfo.iRxShutdownEventFd, &counter, sizeof(counter)); + // EAGAIN result indicates that the counter was already 0 in non-blocking mode. + if(result < 0 && errno != EAGAIN) + { + ANT_ERROR("Could not clear shutdown signal in enable. Reason: %s", strerror(errno)); + goto out; + } + stRxThreadInfo.ucRunThread = 1; for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { @@ -878,11 +908,14 @@ int ant_disable(void) stRxThreadInfo.ucRunThread = 0; - for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { - ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]); - } - if (stRxThreadInfo.stRxThread != 0) { + ANT_DEBUG_I("Sending shutdown signal to rx thread."); + if(write(stRxThreadInfo.iRxShutdownEventFd, &EVENT_FD_PLUS_ONE, sizeof(EVENT_FD_PLUS_ONE)) < 0) + { + ANT_ERROR("failed to signal rx thread with eventfd. Reason: %s", strerror(errno)); + goto out; + } + ANT_DEBUG_I("Waiting for rx thread to finish."); if (pthread_join(stRxThreadInfo.stRxThread, NULL) < 0) { ANT_ERROR("failed to join rx thread: %s", strerror(errno)); goto out; @@ -891,6 +924,10 @@ int ant_disable(void) ANT_DEBUG_D("rx thread is not running"); } + for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { + ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]); + } + iRet = 0; out: diff --git a/src/vfs/ant_rx_chardev.c b/src/vfs/ant_rx_chardev.c index b38757f..aa51825 100644 --- a/src/vfs/ant_rx_chardev.c +++ b/src/vfs/ant_rx_chardev.c @@ -29,11 +29,12 @@ #include <errno.h> #include <poll.h> #include <pthread.h> +#include <stdint.h> /* for uint64_t */ #include "ant_types.h" #include "antradio_power.h" #include "ant_rx_chardev.h" -#include "ant_driver_defines.h" +#include "ant_hci_defines.h" #include "ant_log.h" #include "ant_native.h" // ANT_HCI_MAX_MSG_SIZE, ANT_MSG_ID_OFFSET, ANT_MSG_DATA_OFFSET, // ant_radio_enabled_status() @@ -60,6 +61,11 @@ static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE]; #define EVENTS_TO_LISTEN_FOR (EVENT_DATA_AVAILABLE|EVENT_DISABLE|EVENT_HARD_RESET) +// Plus one is for the eventfd shutdown signal. +#define NUM_POLL_FDS (NUM_ANT_CHANNELS + 1) +#define EVENTFD_IDX NUM_ANT_CHANNELS + +void doReset(ant_rx_thread_info_t *stRxThreadInfo); int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo); /* @@ -87,7 +93,7 @@ void *fnRxThread(void *ant_rx_thread_info) int iMutexLockResult; int iPollRet; ant_rx_thread_info_t *stRxThreadInfo; - struct pollfd astPollFd[NUM_ANT_CHANNELS]; + struct pollfd astPollFd[NUM_POLL_FDS]; ant_channel_type eChannel; ANT_FUNC_START(); @@ -96,29 +102,27 @@ void *fnRxThread(void *ant_rx_thread_info) astPollFd[eChannel].fd = stRxThreadInfo->astChannels[eChannel].iFd; astPollFd[eChannel].events = EVENTS_TO_LISTEN_FOR; } + // Fill out poll request for the shutdown signaller. + astPollFd[EVENTFD_IDX].fd = stRxThreadInfo->iRxShutdownEventFd; + astPollFd[EVENTFD_IDX].events = POLL_IN; /* continue running as long as not terminated */ while (stRxThreadInfo->ucRunThread) { /* Wait for data available on any file (transport path) */ - iPollRet = poll(astPollFd, NUM_ANT_CHANNELS, ANT_POLL_TIMEOUT); + iPollRet = poll(astPollFd, NUM_POLL_FDS, ANT_POLL_TIMEOUT); if (!iPollRet) { ANT_DEBUG_V("poll timed out, checking exit cond"); } else if (iPollRet < 0) { - ANT_ERROR("read thread exiting, unhandled error: %s", strerror(errno)); + ANT_ERROR("unhandled error: %s, attempting recovery.", strerror(errno)); + doReset(stRxThreadInfo); + goto out; } else { for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) { if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_HARD_RESET)) { - ANT_ERROR("poll error from %s. exiting rx thread", + ANT_ERROR("Hard reset indicated by %s. Attempting recovery.", stRxThreadInfo->astChannels[eChannel].pcDevicePath); - /* Chip was reset or other error, only way to recover is to - * close and open ANT chardev */ - stRxThreadInfo->ucChipResetting = 1; - - if (g_fnStateCallback) { - g_fnStateCallback(RADIO_STATUS_RESETTING); - } - - goto reset; + doReset(stRxThreadInfo); + goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DISABLE)) { /* chip reported it was disabled, either unexpectedly or due to us closing the file */ ANT_DEBUG_D( @@ -135,12 +139,36 @@ void *fnRxThread(void *ant_rx_thread_info) // set flag to exit out of Rx Loop stRxThreadInfo->ucRunThread = 0; } + } else if (areAllFlagsSet(astPollFd[eChannel].revents, POLLNVAL)) { + ANT_ERROR("poll was called on invalid file descriptor %s. Attempting recovery.", + stRxThreadInfo->astChannels[eChannel].pcDevicePath); + doReset(stRxThreadInfo); + goto out; + } else if (areAllFlagsSet(astPollFd[eChannel].revents, POLLERR)) { + ANT_ERROR("Unknown error from %s. Attempting recovery.", + stRxThreadInfo->astChannels[eChannel].pcDevicePath); + doReset(stRxThreadInfo); + goto out; } else if (astPollFd[eChannel].revents) { ANT_DEBUG_W("unhandled poll result %#x from %s", astPollFd[eChannel].revents, stRxThreadInfo->astChannels[eChannel].pcDevicePath); } } + // Now check for shutdown signal + if(areAllFlagsSet(astPollFd[EVENTFD_IDX].revents, POLLIN)) + { + ANT_DEBUG_I("rx thread caught shutdown signal."); + // reset the counter by reading. + uint64_t counter; + read(stRxThreadInfo->iRxShutdownEventFd, &counter, sizeof(counter)); + // don't care if read error, going to close the thread anyways. + stRxThreadInfo->ucRunThread = 0; + } else if (astPollFd[EVENTFD_IDX].revents != 0) { + ANT_ERROR("Shutdown event descriptor had unexpected event: %#x. exiting rx thread.", + astPollFd[EVENTFD_IDX].revents); + stRxThreadInfo->ucRunThread = 0; + } } } @@ -177,15 +205,26 @@ void *fnRxThread(void *ant_rx_thread_info) ANT_DEBUG_V("stEnabledStatusLock busy"); } - // FIXME This is not the end of the function - // Probably because goto:reset is a bad implementation; can have a reset function. - // Will only end here on Android. + out: ANT_FUNC_END(); #ifdef ANDROID return NULL; #endif +} + +void doReset(ant_rx_thread_info_t *stRxThreadInfo) +{ + int iMutexLockResult; + + ANT_FUNC_START(); + /* Chip was reset or other error, only way to recover is to + * close and open ANT chardev */ + stRxThreadInfo->ucChipResetting = 1; + + if (g_fnStateCallback) { + g_fnStateCallback(RADIO_STATUS_RESETTING); + } -reset: stRxThreadInfo->ucRunThread = 0; ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__); @@ -220,9 +259,6 @@ reset: stRxThreadInfo->ucChipResetting = 0; ANT_FUNC_END(); -#ifdef ANDROID - return NULL; -#endif } //////////////////////////////////////////////////////////////////// diff --git a/src/vfs/inc/ant_hci_defines.h b/src/vfs/inc/ant_hci_defines.h new file mode 100644 index 0000000..3ffe672 --- /dev/null +++ b/src/vfs/inc/ant_hci_defines.h @@ -0,0 +1,53 @@ +/* + * ANT Stack + * + * Copyright 2013 Dynastream Innovations + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*******************************************************************************\ +* +* FILE NAME: ant_hci_defines.h +* +* BRIEF: +* This file defines ANT specific HCI values used by the ANT chip that are +* not specific to the underlying chip. These should not need to be modified, +* but should be verified they are correct. +* +\*******************************************************************************/ + +#ifndef __VFS_INDEPENDENT_H +#define __VFS_INDEPENDENT_H + +// ANT HCI Packet Structure +// ----------------------------------------- +// | Header | Data | Footer | +// |----------------------|-----------------| +// |Optional| Data | Opt. | ... | Optional | +// | Opcode | Size | Sync | | Checksum | +// Data may include any number of ANT packets, with no sync byte or checksum. +// A read from the driver may return any number of ANT HCI packets. + +#include "ant_driver_defines.h" + +#define ANT_HCI_HEADER_SIZE ((ANT_HCI_OPCODE_SIZE) + (ANT_HCI_SIZE_SIZE) + (ANT_HCI_SYNC_SIZE)) +#define ANT_HCI_FOOTER_SIZE (ANT_HCI_CHECKSUM_SIZE) + +#define ANT_HCI_OPCODE_OFFSET 0 +#define ANT_HCI_SIZE_OFFSET ((ANT_HCI_OPCODE_OFFSET) + (ANT_HCI_OPCODE_SIZE)) +#define ANT_HCI_SYNC_OFFSET ((ANT_HCI_SIZE_OFFSET) + (ANT_HCI_SIZE_SIZE)) +#define ANT_HCI_DATA_OFFSET (ANT_HCI_HEADER_SIZE) + +#define ANT_FLOW_GO_WAIT_TIMEOUT_SEC 10 + +#endif /* ifndef __VFS_INDEPENDENT_H */ diff --git a/src/vfs/inc/ant_rx_chardev.h b/src/vfs/inc/ant_rx_chardev.h index 526070c..1024dac 100644 --- a/src/vfs/inc/ant_rx_chardev.h +++ b/src/vfs/inc/ant_rx_chardev.h @@ -32,7 +32,7 @@ #define __ANT_RX_NATIVE_H #include "ant_native.h" -#include "ant_driver_defines.h" +#include "ant_hci_defines.h" /* same as HCI_MAX_EVENT_SIZE from hci.h, but hci.h is not included for vfs */ #define ANT_HCI_MAX_MSG_SIZE 260 @@ -84,6 +84,8 @@ typedef struct { pthread_mutex_t *pstEnabledStatusLock; /* ANT channels */ ant_channel_info_t astChannels[NUM_ANT_CHANNELS]; + /* Event file descriptor used to interrupt the poll() loop in the rx thread. */ + int iRxShutdownEventFd; } ant_rx_thread_info_t; extern ANTNativeANTStateCb g_fnStateCallback; // TODO State callback should be inside ant_rx_thread_info_t. diff --git a/src/vfs/prerelease/ant_driver_defines.h b/src/vfs/prerelease/ant_driver_defines.h index f2e843b..692de0d 100644 --- a/src/vfs/prerelease/ant_driver_defines.h +++ b/src/vfs/prerelease/ant_driver_defines.h @@ -82,17 +82,4 @@ // That signals Flow Stop: #define ANT_FLOW_STOP ((ANT_U8)0x80) -// ---------------------- NOT CHIP SPECIFIC -// These should not need to be modified, but should be verified they are correct - -#define ANT_HCI_HEADER_SIZE ((ANT_HCI_OPCODE_SIZE) + (ANT_HCI_SIZE_SIZE) + (ANT_HCI_SYNC_SIZE)) -#define ANT_HCI_FOOTER_SIZE (ANT_HCI_CHECKSUM_SIZE) - -#define ANT_HCI_OPCODE_OFFSET 0 -#define ANT_HCI_SIZE_OFFSET ((ANT_HCI_OPCODE_OFFSET) + (ANT_HCI_OPCODE_SIZE)) -#define ANT_HCI_SYNC_OFFSET ((ANT_HCI_SIZE_OFFSET) + (ANT_HCI_SIZE_SIZE)) -#define ANT_HCI_DATA_OFFSET (ANT_HCI_HEADER_SIZE) - -#define ANT_FLOW_GO_WAIT_TIMEOUT_SEC 10 - #endif /* ifndef __VFS_PRERELEASE_H */ diff --git a/src/vfs/ste/cg29xx/ant_driver_defines.h b/src/vfs/ste/cg29xx/ant_driver_defines.h index aa75ffa..c47415d 100644 --- a/src/vfs/ste/cg29xx/ant_driver_defines.h +++ b/src/vfs/ste/cg29xx/ant_driver_defines.h @@ -79,17 +79,4 @@ // That signals Flow Stop: #define ANT_FLOW_STOP ((ANT_U8)0x80) - -// ---------------------- NOT CHIP SPECIFIC -// These should not need to be modified, but should be verified they are correct - -#define ANT_HCI_HEADER_SIZE ((ANT_HCI_OPCODE_SIZE) + (ANT_HCI_SIZE_SIZE) + (ANT_HCI_SYNC_SIZE)) - -#define ANT_HCI_OPCODE_OFFSET 0 -#define ANT_HCI_SIZE_OFFSET ((ANT_HCI_OPCODE_OFFSET) + (ANT_HCI_OPCODE_SIZE)) -#define ANT_HCI_SYNC_OFFSET ((ANT_HCI_SIZE_OFFSET) + (ANT_HCI_SIZE_SIZE)) -#define ANT_HCI_DATA_OFFSET (ANT_HCI_HEADER_SIZE) - -#define ANT_FLOW_GO_WAIT_TIMEOUT_SEC 10 - #endif /* ifndef __VFS_PRERELEASE_H */ |