diff options
author | Sudhir Sharma <sudhshar@codeaurora.org> | 2014-07-08 12:08:02 -0700 |
---|---|---|
committer | Sudhir Sharma <sudhshar@codeaurora.org> | 2014-07-08 12:59:59 -0700 |
commit | 99a134621867f04f0f6c727348a636c655c0b3fc (patch) | |
tree | cec7a29ecc9cae529551fe794bad365a0b2b8326 | |
parent | f834bd6803ea316cfb8c7ba82fc181de91358c36 (diff) | |
parent | 3cb59fb825dd9a6758ab4ba0fff156a54fa1ee73 (diff) | |
download | android_external_ant-wireless_ant_native-99a134621867f04f0f6c727348a636c655c0b3fc.tar.gz android_external_ant-wireless_ant_native-99a134621867f04f0f6c727348a636c655c0b3fc.tar.bz2 android_external_ant-wireless_ant_native-99a134621867f04f0f6c727348a636c655c0b3fc.zip |
Merge tag 'AU_LINUX_ANDROID_KK.04.04.04.010.031' into HEAD
AU_LINUX_ANDROID_KK.04.04.04.010.031 based on quic/aosp/kk
Change-Id: I2105ba3c940a54ce53b22f00a1e70c45514ab692
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | src/bluez_hci/ant_native_hci.c | 4 | ||||
-rw-r--r-- | src/bt-vendor_vfs/ant_rx_chardev.c | 73 | ||||
-rw-r--r-- | src/bt-vendor_vfs/inc/ant_rx_chardev.h | 2 | ||||
-rw-r--r-- | src/common/inc/ant_version.h | 4 | ||||
-rw-r--r-- | src/vfs/ant_rx_chardev.c | 73 | ||||
-rw-r--r-- | src/vfs/inc/ant_rx_chardev.h | 2 |
7 files changed, 129 insertions, 37 deletions
@@ -7,9 +7,9 @@ This repository contains the source to build the ANT HAL library (antradio_libra ### master ### Versions that have been tested and are suitable for consumer devices. -### development ### -The latest, untested, development versions. These are made available for silicon vendors to verify code changes on parts/boards not available to ANT Wireless engineers. +### features/_branch name_ ### +The latest, untested, development versions of new features and fixes. These are made available for silicon vendors to verify code changes on new parts/boards not yet available to ANT Wireless engineers. -### <X>_debug ### -Unmaintained, unsupported and untested code. These branches are purely used as a means of distributing in-progress work between engineers at different sites. They generally contain features and fixes developed by third parties. +### Third party submissions ### +If you have code changes (new features, improvements or bug fixes), you should submit a pull request to master. These will be considered, and added to master if accepted, or a features branch if further verification is required. diff --git a/src/bluez_hci/ant_native_hci.c b/src/bluez_hci/ant_native_hci.c index 55cde44..f247534 100644 --- a/src/bluez_hci/ant_native_hci.c +++ b/src/bluez_hci/ant_native_hci.c @@ -791,6 +791,9 @@ ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg) case ANT_STATUS_TRANSPORT_UNSPECIFIED_ERROR: { ANT_DEBUG_D("Command Complete: ANT_STATUS_UNSPECIFIED_ERROR"); + + // Give the chip a break before we try to resend data. + nanosleep((struct timespec[]){{0, 50000000}}, NULL); time_t currentTime = time(NULL); @@ -798,7 +801,6 @@ ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg) { if(currentTime < endTime) { - nanosleep((struct timespec[]){{0, 50000000}}, NULL); ANT_DEBUG_V("Retrying. Current time = %d. " "End time = %d", (int)currentTime, (int)endTime); diff --git a/src/bt-vendor_vfs/ant_rx_chardev.c b/src/bt-vendor_vfs/ant_rx_chardev.c index a8f150c..69656b2 100644 --- a/src/bt-vendor_vfs/ant_rx_chardev.c +++ b/src/bt-vendor_vfs/ant_rx_chardev.c @@ -45,6 +45,7 @@ extern ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U #define LOG_TAG "antradio_rx" #define ANT_POLL_TIMEOUT ((int)30000) +#define KEEPALIVE_TIMEOUT ((int)5000) static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE]; @@ -56,15 +57,18 @@ static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE]; // Defines for use with the poll() call #define EVENT_DATA_AVAILABLE (POLLIN|POLLRDNORM) -#define EVENT_DISABLE (POLLHUP) +#define EVENT_CHIP_SHUTDOWN (POLLHUP) #define EVENT_HARD_RESET (POLLERR|POLLPRI|POLLRDHUP) -#define EVENTS_TO_LISTEN_FOR (EVENT_DATA_AVAILABLE|EVENT_DISABLE|EVENT_HARD_RESET) +#define EVENTS_TO_LISTEN_FOR (EVENT_DATA_AVAILABLE|EVENT_CHIP_SHUTDOWN|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 +static ANT_U8 KEEPALIVE_MESG[] = {0x01, 0x00, 0x00}; +static ANT_U8 KEEPALIVE_RESP[] = {0x03, 0x40, 0x00, 0x00, 0x28}; + void doReset(ant_rx_thread_info_t *stRxThreadInfo); int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo); @@ -86,6 +90,17 @@ ANT_BOOL areAllFlagsSet(short value, short flags) } /* + * This thread is run occasionally as a detached thread in order to send a keepalive message to the + * chip. + */ +void *fnKeepAliveThread(void *unused) +{ + ANT_DEBUG_V("Sending dummy keepalive message."); + ant_tx_message(sizeof(KEEPALIVE_MESG)/sizeof(ANT_U8), KEEPALIVE_MESG); + return NULL; +} + +/* * This thread waits for ANT messages from a VFS file. */ void *fnRxThread(void *ant_rx_thread_info) @@ -106,12 +121,32 @@ void *fnRxThread(void *ant_rx_thread_info) astPollFd[EVENTFD_IDX].fd = stRxThreadInfo->iRxShutdownEventFd; astPollFd[EVENTFD_IDX].events = POLL_IN; + // Reset the waiting for response, since we don't want a stale value if we were reset. + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; + /* continue running as long as not terminated */ while (stRxThreadInfo->ucRunThread) { - /* Wait for data available on any file (transport path) */ - iPollRet = poll(astPollFd, NUM_POLL_FDS, ANT_POLL_TIMEOUT); + /* Wait for data available on any file (transport path), shorter wait if we just timed out. */ + int timeout = stRxThreadInfo->bWaitingForKeepaliveResponse ? KEEPALIVE_TIMEOUT : ANT_POLL_TIMEOUT; + iPollRet = poll(astPollFd, NUM_POLL_FDS, timeout); if (!iPollRet) { - ANT_DEBUG_V("poll timed out, checking exit cond"); + if(!stRxThreadInfo->bWaitingForKeepaliveResponse) + { + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_TRUE; + // Keep alive is done on a separate thread so that rxThread can handle flow control during + // the message. + pthread_t thread; + // Don't care if it failed as the consequence is just a missed keep-alive. + pthread_create(&thread, NULL, fnKeepAliveThread, NULL); + // Detach the thread so that we don't need to join it later. + pthread_detach(thread); + ANT_DEBUG_V("poll timed out, checking exit cond"); + } else + { + ANT_DEBUG_E("No response to keepalive, attempting recovery."); + doReset(stRxThreadInfo); + goto out; + } } else if (iPollRet < 0) { ANT_ERROR("unhandled error: %s, attempting recovery.", strerror(errno)); doReset(stRxThreadInfo); @@ -123,18 +158,20 @@ void *fnRxThread(void *ant_rx_thread_info) stRxThreadInfo->astChannels[eChannel].pcDevicePath); 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 */ + } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_CHIP_SHUTDOWN)) { + /* chip reported it was unexpectedly disabled */ ANT_DEBUG_D( "poll hang-up from %s. exiting rx thread", stRxThreadInfo->astChannels[eChannel].pcDevicePath); - // set flag to exit out of Rx Loop - stRxThreadInfo->ucRunThread = 0; - + doReset(stRxThreadInfo); + goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DATA_AVAILABLE)) { ANT_DEBUG_D("data on %s. reading it", stRxThreadInfo->astChannels[eChannel].pcDevicePath); + // Doesn't matter what data we received, we know the chip is alive. + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; + if (readChannelMsg(eChannel, &stRxThreadInfo->astChannels[eChannel]) < 0) { // set flag to exit out of Rx Loop stRxThreadInfo->ucRunThread = 0; @@ -233,6 +270,7 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ANT_ERROR("chip was reset, getting state mutex failed: %s", strerror(iMutexLockResult)); stRxThreadInfo->stRxThread = 0; + stRxThreadInfo->ucChipResetting = 0; } else { ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__); @@ -241,7 +279,10 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ant_disable(); - if (ant_enable()) { /* failed */ + int enableResult = ant_enable(); + + stRxThreadInfo->ucChipResetting = 0; + if (enableResult) { /* failed */ if (g_fnStateCallback) { g_fnStateCallback(RADIO_STATUS_DISABLED); } @@ -256,8 +297,6 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__); } - stRxThreadInfo->ucChipResetting = 0; - ANT_FUNC_END(); } @@ -398,11 +437,15 @@ int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo) } else #endif // ANT_MESG_FLOW_CONTROL { - if (pstChnlInfo->fnRxCallback != NULL) { + ANT_U8 *msg = aucRxBuffer[eChannel] + iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET; + ANT_BOOL bIsKeepAliveResponse = memcmp(msg, KEEPALIVE_RESP, sizeof(KEEPALIVE_RESP)/sizeof(ANT_U8)) == 0; + if (bIsKeepAliveResponse) { + ANT_DEBUG_V("Filtered out keepalive response."); + } else if (pstChnlInfo->fnRxCallback != NULL) { // Loop through read data until all HCI packets are written to callback pstChnlInfo->fnRxCallback(iHciDataSize, \ - &aucRxBuffer[eChannel][iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET]); + msg); } else { ANT_WARN("%s rx callback is null", pstChnlInfo->pcDevicePath); } diff --git a/src/bt-vendor_vfs/inc/ant_rx_chardev.h b/src/bt-vendor_vfs/inc/ant_rx_chardev.h index 1024dac..12ba629 100644 --- a/src/bt-vendor_vfs/inc/ant_rx_chardev.h +++ b/src/bt-vendor_vfs/inc/ant_rx_chardev.h @@ -86,6 +86,8 @@ typedef struct { ant_channel_info_t astChannels[NUM_ANT_CHANNELS]; /* Event file descriptor used to interrupt the poll() loop in the rx thread. */ int iRxShutdownEventFd; + /* Indicates whether thread is waiting for a keepalive response. */ + ANT_BOOL bWaitingForKeepaliveResponse; } ant_rx_thread_info_t; extern ANTNativeANTStateCb g_fnStateCallback; // TODO State callback should be inside ant_rx_thread_info_t. diff --git a/src/common/inc/ant_version.h b/src/common/inc/ant_version.h index 47a6b6f..834603c 100644 --- a/src/common/inc/ant_version.h +++ b/src/common/inc/ant_version.h @@ -20,8 +20,8 @@ #define __ANT_VERSION_H
#define LIBANT_STACK_MAJOR "1"
-#define LIBANT_STACK_MINOR "6"
-#define LIBANT_STACK_INCRE "3"
+#define LIBANT_STACK_MINOR "8"
+#define LIBANT_STACK_INCRE "0"
#endif // __ANT_VERSION_H
diff --git a/src/vfs/ant_rx_chardev.c b/src/vfs/ant_rx_chardev.c index aa51825..94c09b1 100644 --- a/src/vfs/ant_rx_chardev.c +++ b/src/vfs/ant_rx_chardev.c @@ -45,6 +45,7 @@ extern ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U #define LOG_TAG "antradio_rx" #define ANT_POLL_TIMEOUT ((int)30000) +#define KEEPALIVE_TIMEOUT ((int)5000) static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE]; @@ -56,15 +57,18 @@ static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE]; // Defines for use with the poll() call #define EVENT_DATA_AVAILABLE (POLLIN|POLLRDNORM) -#define EVENT_DISABLE (POLLHUP) +#define EVENT_CHIP_SHUTDOWN (POLLHUP) #define EVENT_HARD_RESET (POLLERR|POLLPRI|POLLRDHUP) -#define EVENTS_TO_LISTEN_FOR (EVENT_DATA_AVAILABLE|EVENT_DISABLE|EVENT_HARD_RESET) +#define EVENTS_TO_LISTEN_FOR (EVENT_DATA_AVAILABLE|EVENT_CHIP_SHUTDOWN|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 +static ANT_U8 KEEPALIVE_MESG[] = {0x01, 0x00, 0x00}; +static ANT_U8 KEEPALIVE_RESP[] = {0x03, 0x40, 0x00, 0x00, 0x28}; + void doReset(ant_rx_thread_info_t *stRxThreadInfo); int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo); @@ -86,6 +90,17 @@ ANT_BOOL areAllFlagsSet(short value, short flags) } /* + * This thread is run occasionally as a detached thread in order to send a keepalive message to the + * chip. + */ +void *fnKeepAliveThread(void *unused) +{ + ANT_DEBUG_V("Sending dummy keepalive message."); + ant_tx_message(sizeof(KEEPALIVE_MESG)/sizeof(ANT_U8), KEEPALIVE_MESG); + return NULL; +} + +/* * This thread waits for ANT messages from a VFS file. */ void *fnRxThread(void *ant_rx_thread_info) @@ -106,12 +121,32 @@ void *fnRxThread(void *ant_rx_thread_info) astPollFd[EVENTFD_IDX].fd = stRxThreadInfo->iRxShutdownEventFd; astPollFd[EVENTFD_IDX].events = POLL_IN; + // Reset the waiting for response, since we don't want a stale value if we were reset. + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; + /* continue running as long as not terminated */ while (stRxThreadInfo->ucRunThread) { - /* Wait for data available on any file (transport path) */ - iPollRet = poll(astPollFd, NUM_POLL_FDS, ANT_POLL_TIMEOUT); + /* Wait for data available on any file (transport path), shorter wait if we just timed out. */ + int timeout = stRxThreadInfo->bWaitingForKeepaliveResponse ? KEEPALIVE_TIMEOUT : ANT_POLL_TIMEOUT; + iPollRet = poll(astPollFd, NUM_POLL_FDS, timeout); if (!iPollRet) { - ANT_DEBUG_V("poll timed out, checking exit cond"); + if(!stRxThreadInfo->bWaitingForKeepaliveResponse) + { + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_TRUE; + // Keep alive is done on a separate thread so that rxThread can handle flow control during + // the message. + pthread_t thread; + // Don't care if it failed as the consequence is just a missed keep-alive. + pthread_create(&thread, NULL, fnKeepAliveThread, NULL); + // Detach the thread so that we don't need to join it later. + pthread_detach(thread); + ANT_DEBUG_V("poll timed out, checking exit cond"); + } else + { + ANT_DEBUG_E("No response to keepalive, attempting recovery."); + doReset(stRxThreadInfo); + goto out; + } } else if (iPollRet < 0) { ANT_ERROR("unhandled error: %s, attempting recovery.", strerror(errno)); doReset(stRxThreadInfo); @@ -123,18 +158,20 @@ void *fnRxThread(void *ant_rx_thread_info) stRxThreadInfo->astChannels[eChannel].pcDevicePath); 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 */ + } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_CHIP_SHUTDOWN)) { + /* chip reported it was unexpectedly disabled */ ANT_DEBUG_D( "poll hang-up from %s. exiting rx thread", stRxThreadInfo->astChannels[eChannel].pcDevicePath); - // set flag to exit out of Rx Loop - stRxThreadInfo->ucRunThread = 0; - + doReset(stRxThreadInfo); + goto out; } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DATA_AVAILABLE)) { ANT_DEBUG_D("data on %s. reading it", stRxThreadInfo->astChannels[eChannel].pcDevicePath); + // Doesn't matter what data we received, we know the chip is alive. + stRxThreadInfo->bWaitingForKeepaliveResponse = ANT_FALSE; + if (readChannelMsg(eChannel, &stRxThreadInfo->astChannels[eChannel]) < 0) { // set flag to exit out of Rx Loop stRxThreadInfo->ucRunThread = 0; @@ -233,6 +270,7 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ANT_ERROR("chip was reset, getting state mutex failed: %s", strerror(iMutexLockResult)); stRxThreadInfo->stRxThread = 0; + stRxThreadInfo->ucChipResetting = 0; } else { ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__); @@ -241,7 +279,10 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ant_disable(); - if (ant_enable()) { /* failed */ + int enableResult = ant_enable(); + + stRxThreadInfo->ucChipResetting = 0; + if (enableResult) { /* failed */ if (g_fnStateCallback) { g_fnStateCallback(RADIO_STATUS_DISABLED); } @@ -256,8 +297,6 @@ void doReset(ant_rx_thread_info_t *stRxThreadInfo) ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__); } - stRxThreadInfo->ucChipResetting = 0; - ANT_FUNC_END(); } @@ -398,11 +437,15 @@ int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo) } else #endif // ANT_MESG_FLOW_CONTROL { - if (pstChnlInfo->fnRxCallback != NULL) { + ANT_U8 *msg = aucRxBuffer[eChannel] + iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET; + ANT_BOOL bIsKeepAliveResponse = memcmp(msg, KEEPALIVE_RESP, sizeof(KEEPALIVE_RESP)/sizeof(ANT_U8)) == 0; + if (bIsKeepAliveResponse) { + ANT_DEBUG_V("Filtered out keepalive response."); + } else if (pstChnlInfo->fnRxCallback != NULL) { // Loop through read data until all HCI packets are written to callback pstChnlInfo->fnRxCallback(iHciDataSize, \ - &aucRxBuffer[eChannel][iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET]); + msg); } else { ANT_WARN("%s rx callback is null", pstChnlInfo->pcDevicePath); } diff --git a/src/vfs/inc/ant_rx_chardev.h b/src/vfs/inc/ant_rx_chardev.h index a3481b0..d76184e 100644 --- a/src/vfs/inc/ant_rx_chardev.h +++ b/src/vfs/inc/ant_rx_chardev.h @@ -86,6 +86,8 @@ typedef struct { ant_channel_info_t astChannels[NUM_ANT_CHANNELS];
/* Event file descriptor used to interrupt the poll() loop in the rx thread. */
int iRxShutdownEventFd;
+ /* Indicates whether thread is waiting for a keepalive response. */
+ ANT_BOOL bWaitingForKeepaliveResponse;
} ant_rx_thread_info_t;
extern ANTNativeANTStateCb g_fnStateCallback; // TODO State callback should be inside ant_rx_thread_info_t.
|