Merge branch 'qualcomm_uart_debug'
diff --git a/Android.mk b/Android.mk
index 3ee7f89..007a6c3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -24,6 +24,14 @@
 
 include $(CLEAR_VARS)
 
+# For known qualcomm smd devices we remap the chip name to "qualcomm-smd"
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"wcn3680")
+
+BOARD_ANT_WIRELESS_DEVICE := "qualcomm-smd"
+
+endif
+
 ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"wl12xx")
 
 ANT_DIR := src/bluez_hci
@@ -36,6 +44,14 @@
 
 ANT_DIR := src/vfs
 
+else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"qualcomm-smd")
+
+ANT_DIR := src/vfs
+
+else ifeq($(BOARD_ANT_WIRELESS_DEVICE),"qualcomm-uart")
+
+ANT_DIR := src/bt-vendor_vfs
+
 else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"vfs-prerelease")
 
 ANT_DIR := src/vfs
diff --git a/src/bluez_hci/ant_native_hci.c b/src/bluez_hci/ant_native_hci.c
index c2c453f..55cde44 100644
--- a/src/bluez_hci/ant_native_hci.c
+++ b/src/bluez_hci/ant_native_hci.c
@@ -798,6 +798,7 @@
                      {
                         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/Android.mk b/src/bt-vendor_vfs/Android.mk
new file mode 100644
index 0000000..e6813d0
--- /dev/null
+++ b/src/bt-vendor_vfs/Android.mk
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2011 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.
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -g -c -W -Wall -O2
+
+# needed to pull in the header file for libbt-vendor.so
+BDROID_DIR:= external/bluetooth/bluedroid
+
+# Added hci/include to give access to the header for the libbt-vendorso interface.
+LOCAL_C_INCLUDES := \
+   $(LOCAL_PATH)/src/common/inc \
+   $(LOCAL_PATH)/$(ANT_DIR)/inc \
+   $(BDROID_DIR)/hci/include \
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"qualcomm-uart")
+LOCAL_C_INCLUDES += \
+   $(LOCAL_PATH)/$(ANT_DIR)/qualcomm/uart \
+
+endif # BOARD_ANT_WIRELESS_DEVICE = "qualcomm-uart"
+
+LOCAL_SRC_FILES := \
+   $(COMMON_DIR)/JAntNative.cpp \
+   $(COMMON_DIR)/ant_utils.c \
+   $(ANT_DIR)/ant_native_chardev.c \
+   $(ANT_DIR)/ant_rx_chardev.c \
+
+# JNI
+LOCAL_C_INCLUDE += $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES += \
+   libnativehelper \
+
+# logging and dll loading
+LOCAL_SHARED_LIBRARIES += \
+   libcutils \
+   libdl \
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libantradio
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/src/bt-vendor_vfs/ant_native_chardev.c b/src/bt-vendor_vfs/ant_native_chardev.c
new file mode 100644
index 0000000..a90c8c4
--- /dev/null
+++ b/src/bt-vendor_vfs/ant_native_chardev.c
@@ -0,0 +1,1078 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2011 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_native_chardev.c
+*
+*   BRIEF:
+*      This file provides the VFS implementation of ant_native.h
+*      VFS could be Character Device, TTY, etc.
+*
+*
+\******************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h> /* for open() */
+#include <linux/ioctl.h> /* For hard reset */
+#include <pthread.h>
+#include <dlfcn.h> /* needed for runtime dll loading. */
+#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"
+#include "ant_version.h"
+
+#include "antradio_power.h"
+#include "ant_rx_chardev.h"
+#include "ant_hci_defines.h"
+#include "ant_log.h"
+#include "bt_vendor_lib.h" /* used by qualcomms code to call into libbt-vendor.so */
+#include <cutils/properties.h> /* used by qualcomms additions for logging. */
+// The following functions are dummy implementations of the callbacks required by libbt-vendor.
+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* 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) {
+}
+
+// This struct is used to regsiter the dummy callbacks with libbt-vendor
+bt_vendor_interface_t *vendor_interface=NULL;
+static const bt_vendor_callbacks_t vendor_callbacks = {
+  sizeof(bt_vendor_callbacks_t),
+    vendor_fwcfg_cb,
+    vendor_scocfg_cb,
+    vendor_lpm_vnd_cb,
+    vendor_alloc,
+    vendor_dealloc,
+    vendor_xmit_cb,
+    vendor_epilog_cb
+};
+
+#if ANT_HCI_SIZE_SIZE > 1
+#include "ant_utils.h"  // Put HCI Size value across multiple bytes
+#endif
+
+#define MESG_BROADCAST_DATA_ID               ((ANT_U8)0x4E)
+#define MESG_ACKNOWLEDGED_DATA_ID            ((ANT_U8)0x4F)
+#define MESG_BURST_DATA_ID                   ((ANT_U8)0x50)
+#define MESG_EXT_BROADCAST_DATA_ID           ((ANT_U8)0x5D)
+#define MESG_EXT_ACKNOWLEDGED_DATA_ID        ((ANT_U8)0x5E)
+#define MESG_EXT_BURST_DATA_ID               ((ANT_U8)0x5F)
+#define MESG_ADV_BURST_DATA_ID               ((ANT_U8)0x72)
+
+static ant_rx_thread_info_t stRxThreadInfo;
+static pthread_mutex_t stEnabledStatusLock = PTHREAD_MUTEX_INITIALIZER;
+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);
+
+////////////////////////////////////////////////////////////////////
+//  ant_init
+//
+//  Initialises the native environment.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      ANT_STATUS_SUCCESS if intialize completed, else ANT_STATUS_FAILED
+//
+//  Psuedocode:
+/*
+Set variables to defaults
+Initialise each supported path to chip
+Setup eventfd object.
+RESULT = ANT_STATUS_SUCCESS if no problems else ANT_STATUS_FAILED
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_init(void)
+{
+   ANTStatus status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   stRxThreadInfo.stRxThread = 0;
+   stRxThreadInfo.ucRunThread = 0;
+   stRxThreadInfo.ucChipResetting = 0;
+   stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
+   g_fnStateCallback = 0;
+
+#ifdef ANT_DEVICE_NAME // Single transport path
+   ant_channel_init(&stRxThreadInfo.astChannels[SINGLE_CHANNEL], ANT_DEVICE_NAME);
+#else // Separate data/command paths
+   ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
+   ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
+#endif // Separate data/command paths
+
+   // 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;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_deinit
+//
+//  clean up eventfd object
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      ANT_STATUS_SUCCESS
+//
+//  Psuedocode:
+/*
+RESULT = SUCCESS
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_deinit(void)
+{
+   ANTStatus result_status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   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;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//  ant_enable_radio
+//
+//  Powers on the ANT part and initialises the transport to the chip.
+//  Changes occur in part implementing ant_enable() call
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_TRANSPORT_INIT_ERR if could not enable
+//          ANT_STATUS_FAILED if failed to get mutex or init rx thread
+//
+//  Psuedocode:
+/*
+LOCK enable_LOCK
+    State callback: STATE = ENABLING
+    ant enable
+    IF ant_enable success
+        State callback: STATE = ENABLED
+        RESULT = SUCCESS
+    ELSE
+        ant disable
+        State callback: STATE = Current state
+        RESULT = FAILURE
+    ENDIF
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_enable_radio(void)
+{
+   int iLockResult;
+   ANTStatus result_status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
+   iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
+   if(iLockResult) {
+      ANT_ERROR("enable failed to get state lock: %s", strerror(iLockResult));
+      goto out;
+   }
+   ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
+
+   if (g_fnStateCallback) {
+      g_fnStateCallback(RADIO_STATUS_ENABLING);
+   }
+
+   if (ant_enable() < 0) {
+      ANT_ERROR("ant enable failed: %s", strerror(errno));
+
+      ant_disable();
+
+      if (g_fnStateCallback) {
+         g_fnStateCallback(ant_radio_enabled_status());
+      }
+   } else {
+      if (g_fnStateCallback) {
+         g_fnStateCallback(RADIO_STATUS_ENABLED);
+      }
+
+      result_status = ANT_STATUS_SUCCESS;
+   }
+
+   ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&stEnabledStatusLock);
+   ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
+
+out:
+   ANT_FUNC_END();
+   return result_status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_radio_hard_reset
+//
+//  IF SUPPORTED triggers a hard reset of the chip providing ANT functionality.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_NOT_SUPPORTED if the chip can't hard reset
+//          ANT_STATUS_FAILED if failed to get mutex or enable
+//
+//  Psuedocode:
+/*
+IF Hard Reset not supported
+    RESULT = NOT SUPPORTED
+ELSE
+  LOCK enable_LOCK
+  IF Lock failed
+        RESULT = FAILED
+  ELSE
+    Set Flag Rx thread that chip is resetting
+    FOR each path to chip
+        Send Reset IOCTL to path
+    ENDFOR
+    ant disable
+    ant enable
+    IF ant_enable success
+        State callback: STATE = RESET
+        RESULT = SUCCESS
+    ELSE
+        State callback: STATE = DISABLED
+        RESULT = FAILURE
+    ENDIF
+    Clear Flag Rx thread that chip is resetting
+  UNLOCK
+ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_radio_hard_reset(void)
+{
+   ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
+   ANT_FUNC_START();
+
+#ifdef ANT_IOCTL_RESET
+   ant_channel_type eChannel;
+   int iLockResult;
+
+   result_status = ANT_STATUS_FAILED;
+
+   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
+   iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
+   if(iLockResult) {
+      ANT_ERROR("enable failed to get state lock: %s", strerror(iLockResult));
+      goto out;
+   }
+   ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
+
+   stRxThreadInfo.ucChipResetting = 1;
+   if (g_fnStateCallback)
+      g_fnStateCallback(RADIO_STATUS_RESETTING);
+
+#ifdef ANT_IOCTL_RESET_PARAMETER
+   ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET, ANT_IOCTL_RESET_PARAMETER);
+#else
+   ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET);
+#endif  // ANT_IOCTL_RESET_PARAMETER
+
+   ant_disable();
+
+   if (ant_enable()) { /* failed */
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_DISABLED);
+   } else { /* success */
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_RESET);
+      result_status = ANT_STATUS_SUCCESS;
+   }
+   stRxThreadInfo.ucChipResetting = 0;
+
+   ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&stEnabledStatusLock);
+   ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
+out:
+#endif // ANT_IOCTL_RESET
+
+   ANT_FUNC_END();
+   return result_status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_disable_radio
+//
+//  Powers off the ANT part and closes the transport to the chip.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_FAILED if failed to get mutex
+//
+//  Psuedocode:
+/*
+LOCK enable_LOCK
+    State callback: STATE = DISABLING
+    ant disable
+    State callback: STATE = Current state
+    RESULT = SUCCESS
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_disable_radio(void)
+{
+   int iLockResult;
+   ANTStatus ret = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
+   iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
+   if(iLockResult) {
+      ANT_ERROR("disable failed to get state lock: %s", strerror(iLockResult));
+      goto out;
+   }
+   ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
+
+   if (g_fnStateCallback) {
+      g_fnStateCallback(RADIO_STATUS_DISABLING);
+   }
+
+   ant_disable();
+
+   if (g_fnStateCallback) {
+      g_fnStateCallback(ant_radio_enabled_status());
+   }
+
+   ret = ANT_STATUS_SUCCESS;
+
+   ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&stEnabledStatusLock);
+   ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
+
+out:
+   ANT_FUNC_END();
+   return ret;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_radio_enabled_status
+//
+//  Gets the current chip/transport state; either disabled, disabling,
+//  enabling, enabled, or resetting.  Determines this on the fly by checking
+//  if Rx thread is running and how many of the paths for the ANT chip have
+//  open VFS files.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      The current radio status (ANTRadioEnabledStatus)
+//
+//  Psuedocode:
+/*
+IF Thread Resetting Flag is set
+    RESULT = Resetting
+ELSE
+    COUNT the number of open files
+    IF Thread Run Flag is Not Set
+        IF there are open files OR Rx thread exists
+            RESULT = Disabling
+        ELSE
+            RESULT = Disabled
+        ENDIF
+    ELSE
+        IF All files are open (all paths) AND Rx thread exists
+            RESULT = ENABLED
+        ELSE IF there are open files (Not 0 open files) AND Rx thread exists
+            RESULT = UNKNOWN
+        ELSE (0 open files or Rx thread does not exist [while Thread Run set])
+            RESULT = ENABLING
+        ENDIF
+    ENDIF
+ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTRadioEnabledStatus ant_radio_enabled_status(void)
+{
+   ant_channel_type eChannel;
+   int iOpenFiles = 0;
+   int iOpenThread;
+   ANTRadioEnabledStatus uiRet = RADIO_STATUS_UNKNOWN;
+   ANT_FUNC_START();
+
+   if (stRxThreadInfo.ucChipResetting) {
+      uiRet = RADIO_STATUS_RESETTING;
+      goto out;
+   }
+
+   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
+      if (stRxThreadInfo.astChannels[eChannel].iFd != -1) {
+         iOpenFiles++;
+      }
+   }
+
+   iOpenThread = (stRxThreadInfo.stRxThread) ? 1 : 0;
+
+   if (!stRxThreadInfo.ucRunThread) {
+      if (iOpenFiles || iOpenThread) {
+         uiRet = RADIO_STATUS_DISABLING;
+      } else {
+         uiRet = RADIO_STATUS_DISABLED;
+      }
+   } else {
+      if ((iOpenFiles == NUM_ANT_CHANNELS) && iOpenThread) {
+         uiRet = RADIO_STATUS_ENABLED;
+      } else if (!iOpenFiles && iOpenThread) {
+         uiRet = RADIO_STATUS_UNKNOWN;
+      } else {
+         uiRet = RADIO_STATUS_ENABLING;
+      }
+   }
+
+out:
+   ANT_DEBUG_D("get radio enabled status returned %d", uiRet);
+
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+////////////////////////////////////////////////////////////////////
+//  set_ant_rx_callback
+//
+//  Sets which function to call when an ANT message is received.
+//
+//  Parameters:
+//      rx_callback_func   the ANTNativeANTEventCb function to be used for
+//                         received messages (from all transport paths).
+//
+//  Returns:
+//          ANT_STATUS_SUCCESS
+//
+//  Psuedocode:
+/*
+FOR each transport path
+    Path Rx Callback = rx_callback_func
+ENDFOR
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
+{
+   ANTStatus status = ANT_STATUS_SUCCESS;
+   ANT_FUNC_START();
+
+#ifdef ANT_DEVICE_NAME // Single transport path
+   stRxThreadInfo.astChannels[SINGLE_CHANNEL].fnRxCallback = rx_callback_func;
+#else // Separate data/command paths
+   stRxThreadInfo.astChannels[COMMAND_CHANNEL].fnRxCallback = rx_callback_func;
+   stRxThreadInfo.astChannels[DATA_CHANNEL].fnRxCallback = rx_callback_func;
+#endif // Separate data/command paths
+
+   ANT_FUNC_END();
+   return status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  set_ant_state_callback
+//
+//  Sets which function to call when an ANT state change occurs.
+//
+//  Parameters:
+//      state_callback_func   the ANTNativeANTStateCb function to be used
+//                            for received state changes.
+//
+//  Returns:
+//          ANT_STATUS_SUCCESS
+//
+//  Psuedocode:
+/*
+    State Callback = state_callback_func
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func)
+{
+   ANTStatus status = ANT_STATUS_SUCCESS;
+   ANT_FUNC_START();
+
+   g_fnStateCallback = state_callback_func;
+
+   ANT_FUNC_END();
+   return status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_tx_message_flowcontrol_wait
+//
+//  Sends an ANT message to the chip and waits for a CTS signal
+//
+//  Parameters:
+//      eTxPath          device to transmit message on
+//      eFlowMessagePath device that receives CTS
+//      ucMessageLength  the length of the message
+//      pucMesg          pointer to the message data
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failure:
+//          ANT_STATUS_NOT_ENABLED
+//
+//  Psuedocode:
+/*
+        LOCK flow control
+        IF Lock failed
+            RESULT = FAILED
+        ELSE
+            SET flowMessagePath Flow Control response as FLOW_STOP
+            WRITE txBuffer to txPath (only length of packet part)
+            IF Wrote less then 0 bytes
+                Log error
+                RESULT = FAILED
+            ELSE IF Didn't write 'length of packet' bytes
+                Log error
+                RESULT = FAILED
+            ELSE
+                IF flowMessagePath Flow Control response is not FLOW_GO
+                    WAIT until flowMessagePath Flow Control response is FLOW_GO, UNTIL FLOW_GO Wait Timeout seconds (10) from Now
+                    IF error Waiting
+                        IF error is Timeout
+                            RESULT = HARDWARE ERROR
+                        ELSE
+                            RESULT = FAILED
+                        ENDIF
+                    ELSE
+                        RESULT = SUCCESS
+                    ENDIF
+                ELSE
+                    RESULT = SUCCESS;
+                ENDIF
+            ENDIF
+            UNLOCK flow control
+        ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_tx_message_flowcontrol_wait(ant_channel_type eTxPath, ant_channel_type eFlowMessagePath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage)
+{
+   int iMutexResult;
+   int iResult;
+   struct timespec stTimeout;
+   int iCondWaitResult;
+   ANTStatus status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting stFlowControlLock in %s", __FUNCTION__);
+   iMutexResult = pthread_mutex_lock(&stFlowControlLock);
+   if (iMutexResult) {
+      ANT_ERROR("failed to lock flow control mutex during tx: %s", strerror(iMutexResult));
+      goto out;
+   }
+   ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);
+
+   stRxThreadInfo.astChannels[eFlowMessagePath].ucFlowControlResp = ANT_FLOW_STOP;
+
+#ifdef ANT_FLOW_RESEND
+   // Store Tx message so can resend it from Rx thread
+   stRxThreadInfo.astChannels[eFlowMessagePath].ucResendMessageLength = ucMessageLength;
+   stRxThreadInfo.astChannels[eFlowMessagePath].pucResendMessage = pucTxMessage;
+#endif // ANT_FLOW_RESEND
+
+   iResult = write(stRxThreadInfo.astChannels[eTxPath].iFd, pucTxMessage, ucMessageLength);
+   if (iResult < 0) {
+      ANT_ERROR("failed to write data message to device: %s", strerror(errno));
+   } else if (iResult != ucMessageLength) {
+      ANT_ERROR("bytes written and message size don't match up");
+   } else {
+      stTimeout.tv_sec = time(0) + ANT_FLOW_GO_WAIT_TIMEOUT_SEC;
+      stTimeout.tv_nsec = 0;
+
+      while (stRxThreadInfo.astChannels[eFlowMessagePath].ucFlowControlResp != ANT_FLOW_GO) {
+         iCondWaitResult = pthread_cond_timedwait(&stFlowControlCond, &stFlowControlLock, &stTimeout);
+         if (iCondWaitResult) {
+            ANT_ERROR("failed to wait for flow control response: %s", strerror(iCondWaitResult));
+
+            if (iCondWaitResult == ETIMEDOUT) {
+               status = ANT_STATUS_HARDWARE_ERR;
+
+#ifdef ANT_FLOW_RESEND
+               // Clear Tx message so will stop resending it from Rx thread
+               stRxThreadInfo.astChannels[eFlowMessagePath].ucResendMessageLength = 0;
+               stRxThreadInfo.astChannels[eFlowMessagePath].pucResendMessage = NULL;
+#endif // ANT_FLOW_RESEND
+            }
+            goto wait_error;
+         }
+      }
+
+      status = ANT_STATUS_SUCCESS;
+   }
+
+wait_error:
+   ANT_DEBUG_V("releasing stFlowControlLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&stFlowControlLock);
+   ANT_DEBUG_V("released stFlowControlLock in %s", __FUNCTION__);
+
+out:
+   ANT_FUNC_END();
+   return status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_tx_message_flowcontrol_none
+//
+//  Sends an ANT message to the chip without waiting for flow control
+//
+//  Parameters:
+//      eTxPath         device to transmit on
+//      ucMessageLength the length of the message
+//      pucMesg         pointer to the message data
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failure:
+//          ANT_STATUS_NOT_ENABLED
+//
+//  Psuedocode:
+/*
+        WRITE txBuffer to Tx Path (only length of packet part)
+        IF Wrote less then 0 bytes
+            Log error
+            RESULT = FAILED
+        ELSE IF Didn't write 'length of packet' bytes
+            Log error
+            RESULT = FAILED
+        ELSE
+            RESULT = SUCCESS
+        ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage)
+{
+   int iResult;
+   ANTStatus status = ANT_STATUS_FAILED;\
+   ANT_FUNC_START();
+
+   iResult = write(stRxThreadInfo.astChannels[eTxPath].iFd, pucTxMessage, ucMessageLength);
+   if (iResult < 0) {
+      ANT_ERROR("failed to write message to device: %s", strerror(errno));
+   }  else if (iResult != ucMessageLength) {
+      ANT_ERROR("bytes written and message size don't match up");
+   } else {
+      status = ANT_STATUS_SUCCESS;
+   }
+
+   ANT_FUNC_END();
+   return status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_tx_message
+//
+//  Frames ANT data and decides which flow control method to use for sending the
+//  ANT message to the chip
+//
+//  Parameters:
+//      ucLen   the length of the message
+//      pucMesg pointer to the message data
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failure:
+//          ANT_STATUS_NOT_ENABLED
+//
+//  Psuedocode:
+/*
+IF not enabled
+    RESULT = BT NOT INITIALIZED
+ELSE
+    Create txBuffer, MAX HCI Message Size large
+    PUT ucLen in txBuffer AT ANT HCI Size Offset (0)
+    COPY pucMesg to txBuffer AT ANT HCI Header Size (1)     <- ? Not at offset?
+    LOG txBuffer as a serial Tx (only length of packet part)
+    IF is a data message
+        Tx message on Data Path with FLOW_GO/FLOW_STOP flow control (ant_tx_message_flowcontrol_go_stop())
+    ELSE
+        Tx message on Command Path with no flow control (ant_tx_message_flowcontrol_none())
+    ENDIF
+ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg)
+{
+   // During a tx we must prepend a packet type byte. Thus HCI_PACKET_TYPE_SIZE is added
+   // to all offsets when writing into the tx buffer.
+   ANTStatus status = ANT_STATUS_FAILED;
+   // TODO ANT_HCI_MAX_MSG_SIZE is transport (driver) dependent.
+   ANT_U8 txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_MAX_MSG_SIZE];
+   // TODO Message length can be greater than ANT_U8 can hold.
+   // Not changed as ANT_SERIAL takes length as ANT_U8.
+   ANT_U8 txMessageLength = HCI_PACKET_TYPE_SIZE + ucLen + ANT_HCI_HEADER_SIZE;
+   ANT_FUNC_START();
+
+   if (ant_radio_enabled_status() != RADIO_STATUS_ENABLED) {
+      status = ANT_STATUS_FAILED_BT_NOT_INITIALIZED;
+      goto out;
+   }
+
+#if ANT_HCI_OPCODE_SIZE == 1
+   txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_OPCODE_OFFSET] = ANT_HCI_OPCODE_TX;
+#elif ANT_HCI_OPCODE_SIZE > 1
+#error "Specified ANT_HCI_OPCODE_SIZE not currently supported"
+#endif
+
+#if ANT_HCI_SIZE_SIZE == 1
+   txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_SIZE_OFFSET] = ucLen;
+#elif ANT_HCI_SIZE_SIZE == 2
+   ANT_UTILS_StoreLE16(txBuffer + HCI_PACKET_TYPE_SIZE + ANT_HCI_SIZE_OFFSET, (ANT_U16)ucLen);
+#else
+#error "Specified ANT_HCI_SIZE_SIZE not currently supported"
+#endif
+
+   memcpy(txBuffer + HCI_PACKET_TYPE_SIZE + ANT_HCI_HEADER_SIZE, pucMesg, ucLen);
+
+// We no longer do the serial logging here because the packet type byte is not yet written.
+//ANT_SERIAL(txBuffer, txMessageLength, 'T');
+
+// We only do this if we are using single physical and logical channels.
+#if defined(ANT_DEVICE_NAME) && (HCI_PACKET_TYPE_SIZE == 0) // Single transport path
+   ANT_SERIAL(txBuffer, txMessageLength, 'T');
+   status = ant_tx_message_flowcontrol_wait(SINGLE_CHANNEL, SINGLE_CHANNEL, txMessageLength, txBuffer);
+#else // Separate data/command paths
+   // Each path follows this structure:
+   // write the packet type if needed.
+   // log the packet
+   // Send using the appropriate physical channel, waiting for flow control for data commands.
+   switch (txBuffer[HCI_PACKET_TYPE_SIZE + ANT_HCI_DATA_OFFSET + ANT_MSG_ID_OFFSET]) {
+   case MESG_BROADCAST_DATA_ID:
+   case MESG_ACKNOWLEDGED_DATA_ID:
+   case MESG_BURST_DATA_ID:
+   case MESG_EXT_BROADCAST_DATA_ID:
+   case MESG_EXT_ACKNOWLEDGED_DATA_ID:
+   case MESG_EXT_BURST_DATA_ID:
+   case MESG_ADV_BURST_DATA_ID:
+      ANT_DEBUG_V("Data Path");
+      #if HCI_PACKET_TYPE_SIZE == 1
+      txBuffer[0] = ANT_DATA_TYPE_PACKET;
+      #elif HCI_PACKET_TYPE_SIZE > 1
+      #error "Specified HCI_PACKET_TYPE_SIZE not supported"
+      #endif
+      ANT_SERIAL(txBuffer, txMessageLength, 'T');
+      #ifdef ANT_DEVICE_NAME
+      status = ant_tx_message_flowcontrol_wait(SINGLE_CHANNEL, SINGLE_CHANNEL, txMessageLength, txBuffer);
+      #else
+      status = ant_tx_message_flowcontrol_wait(DATA_CHANNEL, COMMAND_CHANNEL, txMessageLength, txBuffer);
+      #endif
+      break;
+   default:
+      ANT_DEBUG_V("Control Path");
+      #if HCI_PACKET_TYPE_SIZE == 1
+      txBuffer[0] = ANT_CMD_TYPE_PACKET;
+      #elif HCI_PACKET_TYPE_SIZE > 1
+      #error "Specified HCI_PACKET_TYPE_SIZE not supported"
+      #endif
+      ANT_SERIAL(txBuffer, txMessageLength, 'T');
+      #ifdef ANT_DEVICE_NAME
+      status = ant_tx_message_flowcontrol_none(SINGLE_CHANNEL, txMessageLength, txBuffer);
+      #else
+      status = ant_tx_message_flowcontrol_none(COMMAND_CHANNEL, txMessageLength, txBuffer);
+      #endif
+   }
+#endif // Separate data/command paths
+
+out:
+   ANT_FUNC_END();
+   return status;
+}
+
+//----------------- TODO Move these somewhere for multi transport path / dedicated channel support:
+
+static void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName)
+{
+   ANT_FUNC_START();
+
+   // TODO Don't need to store, only accessed when trying to open:
+   // Is however useful for logs.
+   pstChnlInfo->pcDevicePath = pcCharDevName;
+
+   // This is the only piece of info that needs to be stored per channel
+   pstChnlInfo->iFd = -1;
+
+   // TODO Only 1 of these (not per-channel) is actually ever used:
+   pstChnlInfo->fnRxCallback = NULL;
+   pstChnlInfo->ucFlowControlResp = ANT_FLOW_GO;
+#ifdef ANT_FLOW_RESEND
+   pstChnlInfo->ucResendMessageLength = 0;
+   pstChnlInfo->pucResendMessage = NULL;
+#endif // ANT_FLOW_RESEND
+   // TODO Only used when Flow Control message received, so must only be Command path Rx thread
+   pstChnlInfo->pstFlowControlCond = &stFlowControlCond;
+   pstChnlInfo->pstFlowControlLock = &stFlowControlLock;
+
+   ANT_FUNC_END();
+}
+
+// This function is used as an alternative to opening the char device directly.
+// It is needed as libbt-vendor does the power up/down control for us when we open/close the file descriptor.
+int init_transport_bdroid(int on) {
+
+    void *so_handle;
+    unsigned char bdaddr[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
+    int  fd[CH_MAX], powerstate, ret;
+
+    if (on) {
+        so_handle = dlopen("libbt-vendor.so", RTLD_NOW);
+        if (!so_handle)
+        {
+           ALOGE("Failed to load vendor component");
+           return -1;
+        }
+
+        vendor_interface = (bt_vendor_interface_t *) dlsym(so_handle, "BLUETOOTH_VENDOR_LIB_INTERFACE");
+        if (!vendor_interface)
+        {
+            ALOGE("Failed to accesst bt vendor interface");
+            return -1;
+        }
+
+        vendor_interface->init(&vendor_callbacks, bdaddr);
+
+        ALOGI("Turn On BT power");
+        powerstate = BT_VND_PWR_ON;
+        ret = vendor_interface->op(BT_VND_OP_POWER_CTRL, &powerstate);
+        if (ret < 0)
+        {
+            ALOGE("Failed to turn on power from  bt vendor interface");
+            return -1;
+        }
+        /*call ANT_USERIAL_OPEN to get ANT handle*/
+        ret = vendor_interface->op(BT_VND_OP_ANT_USERIAL_OPEN, fd);
+        ALOGE("ret value: %d", ret);
+        if (ret != 1)
+        {
+            ALOGE("Failed to get fd from  bt vendor interface");
+            return -1;
+        } else {
+            ALOGE("FD: %x", fd[0]);
+            return fd[0];
+        }
+    } else {
+        if (vendor_interface) {
+            ALOGE("Close and cleanup the interfaces");
+            int ret = vendor_interface->op(BT_VND_OP_ANT_USERIAL_CLOSE, NULL);
+
+            ALOGE("ret value: %d", ret);
+            ALOGI("Turn off BT power");
+            powerstate = BT_VND_PWR_OFF;
+            ret = vendor_interface->op(BT_VND_OP_POWER_CTRL, &powerstate);
+            if (ret < 0)
+            {
+                ALOGE("Failed to turn off power from  bt vendor interface");
+                return -1;
+            }
+            vendor_interface->cleanup();
+            vendor_interface = NULL;
+            return 0;
+        } else {
+
+            ALOGE("Not able to find vendor interface handle");
+            return -1;
+        }
+    }
+}
+
+static void ant_disable_channel(ant_channel_info_t *pstChnlInfo)
+{
+   ANT_FUNC_START();
+   if (!pstChnlInfo) {
+      ANT_ERROR("null channel info passed to channel disable function");
+      goto out;
+   }
+   if (pstChnlInfo->iFd != -1) {
+      // Use the new init_transport function instead of open() to get our fd.
+      if (init_transport_bdroid(0) < 0) {
+         ANT_ERROR("failed to close channel %s(%#x): %s", pstChnlInfo->pcDevicePath, pstChnlInfo->iFd, strerror(errno));
+      }
+
+      pstChnlInfo->iFd = -1; //TODO can this overwrite a still valid fd?
+   } else {
+      ANT_DEBUG_D("%s file is already closed", pstChnlInfo->pcDevicePath);
+   }
+
+out:
+   ANT_FUNC_END();
+}
+
+static int ant_enable_channel(ant_channel_info_t *pstChnlInfo)
+{
+   int iRet = -1;
+   ANT_FUNC_START();
+   if (!pstChnlInfo) {
+      ANT_ERROR("null channel info passed to channel enable function");
+      errno = EINVAL;
+      goto out;
+   }
+   if (pstChnlInfo->iFd == -1) {
+      // Use the init_transport function to release our fd instead of close()
+      pstChnlInfo->iFd = init_transport_bdroid(1);
+      if (pstChnlInfo->iFd < 0) {
+         ANT_ERROR("failed to open dev %s: %s", pstChnlInfo->pcDevicePath, strerror(errno));
+         goto out;
+      }
+   } else {
+      ANT_DEBUG_D("%s is already enabled", pstChnlInfo->pcDevicePath);
+   }
+   iRet = 0;
+out:
+   ANT_FUNC_END();
+   return iRet;
+}
+
+//----------------------------------------------------------------------- This is antradio_power.h:
+
+int ant_enable(void)
+{
+   int iRet = -1;
+   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++) {
+      if (ant_enable_channel(&stRxThreadInfo.astChannels[eChannel]) < 0) {
+         ANT_ERROR("failed to enable channel %s: %s",
+                         stRxThreadInfo.astChannels[eChannel].pcDevicePath,
+                         strerror(errno));
+         goto out;
+      }
+   }
+
+   if (stRxThreadInfo.stRxThread == 0) {
+      if (pthread_create(&stRxThreadInfo.stRxThread, NULL, fnRxThread, &stRxThreadInfo) < 0) {
+         ANT_ERROR("failed to start rx thread: %s", strerror(errno));
+         goto out;
+      }
+   } else {
+      ANT_DEBUG_D("rx thread is already running");
+   }
+
+   if (!stRxThreadInfo.ucRunThread) {
+      ANT_ERROR("rx thread crashed during init");
+      goto out;
+   }
+
+   iRet = 0;
+
+out:
+   ANT_FUNC_END();
+   return iRet;
+}
+
+int ant_disable(void)
+{
+   int iRet = -1;
+   ant_channel_type eChannel;
+   ANT_FUNC_START();
+
+   stRxThreadInfo.ucRunThread = 0;
+
+   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;
+      }
+   } else {
+      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:
+   stRxThreadInfo.stRxThread = 0;
+   ANT_FUNC_END();
+   return iRet;
+}
+
+//---------------------------------------------------------
+
+const char *ant_get_lib_version()
+{
+   return "libantradio.so: "ANT_CHIP_NAME". Version "
+      LIBANT_STACK_MAJOR"."LIBANT_STACK_MINOR"."LIBANT_STACK_INCRE;
+}
diff --git a/src/bt-vendor_vfs/ant_rx_chardev.c b/src/bt-vendor_vfs/ant_rx_chardev.c
new file mode 100644
index 0000000..a8f150c
--- /dev/null
+++ b/src/bt-vendor_vfs/ant_rx_chardev.c
@@ -0,0 +1,421 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2011 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_rx_chardev.c
+*
+*   BRIEF:
+*      This file implements the receive thread function which will loop reading
+*      ANT messages until told to exit.
+*
+*
+\******************************************************************************/
+
+#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_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()
+
+extern ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage);
+
+#undef LOG_TAG
+#define LOG_TAG "antradio_rx"
+
+#define ANT_POLL_TIMEOUT         ((int)30000)
+
+static ANT_U8 aucRxBuffer[NUM_ANT_CHANNELS][ANT_HCI_MAX_MSG_SIZE];
+
+#ifdef ANT_DEVICE_NAME // Single transport path
+   static int iRxBufferLength[NUM_ANT_CHANNELS] = {0};
+#else
+   static int iRxBufferLength[NUM_ANT_CHANNELS] = {0, 0};
+#endif //
+
+// Defines for use with the poll() call
+#define EVENT_DATA_AVAILABLE (POLLIN|POLLRDNORM)
+#define EVENT_DISABLE (POLLHUP)
+#define EVENT_HARD_RESET (POLLERR|POLLPRI|POLLRDHUP)
+
+#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);
+
+/*
+ * Function to check that all given flags are set in a particular value.
+ * Designed for use with the revents field of pollfds filled out by poll().
+ *
+ * Parameters:
+ *    - value: The value that will be checked to contain all flags.
+ *    - flags: Bitwise-or of the flags that value should be checked for.
+ *
+ * Returns:
+ *    - true IFF all the bits that are set in 'flags' are also set in 'value'
+ */
+ANT_BOOL areAllFlagsSet(short value, short flags)
+{
+   value &= flags;
+   return (value == flags);
+}
+
+/*
+ * This thread waits for ANT messages from a VFS file.
+ */
+void *fnRxThread(void *ant_rx_thread_info)
+{
+   int iMutexLockResult;
+   int iPollRet;
+   ant_rx_thread_info_t *stRxThreadInfo;
+   struct pollfd astPollFd[NUM_POLL_FDS];
+   ant_channel_type eChannel;
+   ANT_FUNC_START();
+
+   stRxThreadInfo = (ant_rx_thread_info_t *)ant_rx_thread_info;
+   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
+      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_POLL_FDS, ANT_POLL_TIMEOUT);
+      if (!iPollRet) {
+         ANT_DEBUG_V("poll timed out, checking exit cond");
+      } else if (iPollRet < 0) {
+         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("Hard reset indicated by %s. Attempting recovery.",
+                            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 */
+               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;
+
+            } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DATA_AVAILABLE)) {
+               ANT_DEBUG_D("data on %s. reading it",
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+
+               if (readChannelMsg(eChannel, &stRxThreadInfo->astChannels[eChannel]) < 0) {
+                  // 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;
+         }
+      }
+   }
+
+   /* disable ANT radio if not already disabling */
+   // Try to get stEnabledStatusLock.
+   // if you get it then no one is enabling or disabling
+   // if you can't get it assume something made you exit
+   ANT_DEBUG_V("try getting stEnabledStatusLock in %s", __FUNCTION__);
+   iMutexLockResult = pthread_mutex_trylock(stRxThreadInfo->pstEnabledStatusLock);
+   if (!iMutexLockResult) {
+      ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
+      ANT_WARN("rx thread has unexpectedly crashed, cleaning up");
+
+      // spoof our handle as closed so we don't try to join ourselves in disable
+      stRxThreadInfo->stRxThread = 0;
+
+      if (g_fnStateCallback) {
+         g_fnStateCallback(RADIO_STATUS_DISABLING);
+      }
+
+      ant_disable();
+
+      if (g_fnStateCallback) {
+         g_fnStateCallback(ant_radio_enabled_status());
+      }
+
+      ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
+      pthread_mutex_unlock(stRxThreadInfo->pstEnabledStatusLock);
+      ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
+   } else if (iMutexLockResult != EBUSY) {
+      ANT_ERROR("rx thread closing code, trylock on state lock failed: %s",
+            strerror(iMutexLockResult));
+   } else {
+      ANT_DEBUG_V("stEnabledStatusLock busy");
+   }
+
+   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);
+   }
+
+   stRxThreadInfo->ucRunThread = 0;
+
+   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
+   iMutexLockResult = pthread_mutex_lock(stRxThreadInfo->pstEnabledStatusLock);
+   if (iMutexLockResult < 0) {
+      ANT_ERROR("chip was reset, getting state mutex failed: %s",
+            strerror(iMutexLockResult));
+      stRxThreadInfo->stRxThread = 0;
+   } else {
+      ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
+
+      stRxThreadInfo->stRxThread = 0; /* spoof our handle as closed so we don't
+                                       * try to join ourselves in disable */
+
+      ant_disable();
+
+      if (ant_enable()) { /* failed */
+         if (g_fnStateCallback) {
+            g_fnStateCallback(RADIO_STATUS_DISABLED);
+         }
+      } else { /* success */
+         if (g_fnStateCallback) {
+            g_fnStateCallback(RADIO_STATUS_RESET);
+         }
+      }
+
+      ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
+      pthread_mutex_unlock(stRxThreadInfo->pstEnabledStatusLock);
+      ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
+   }
+
+   stRxThreadInfo->ucChipResetting = 0;
+
+   ANT_FUNC_END();
+}
+
+////////////////////////////////////////////////////////////////////
+//  setFlowControl
+//
+//  Sets the flow control "flag" to the value provided and signals the transmit
+//  thread to check the value.
+//
+//  Parameters:
+//      pstChnlInfo   the details of the channel being updated
+//      ucFlowSetting the value to use
+//
+//  Returns:
+//      Success:
+//          0
+//      Failure:
+//          -1
+////////////////////////////////////////////////////////////////////
+int setFlowControl(ant_channel_info_t *pstChnlInfo, ANT_U8 ucFlowSetting)
+{
+   int iRet = -1;
+   int iMutexResult;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting stFlowControlLock in %s", __FUNCTION__);
+   iMutexResult = pthread_mutex_lock(pstChnlInfo->pstFlowControlLock);
+   if (iMutexResult) {
+      ANT_ERROR("failed to lock flow control mutex during response: %s", strerror(iMutexResult));
+   } else {
+      ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);
+
+      pstChnlInfo->ucFlowControlResp = ucFlowSetting;
+
+      ANT_DEBUG_V("releasing stFlowControlLock in %s", __FUNCTION__);
+      pthread_mutex_unlock(pstChnlInfo->pstFlowControlLock);
+      ANT_DEBUG_V("released stFlowControlLock in %s", __FUNCTION__);
+
+      pthread_cond_signal(pstChnlInfo->pstFlowControlCond);
+
+      iRet = 0;
+   }
+
+   ANT_FUNC_END();
+   return iRet;
+}
+
+int readChannelMsg(ant_channel_type eChannel, ant_channel_info_t *pstChnlInfo)
+{
+   int iRet = -1;
+   int iRxLenRead;
+   int iCurrentHciPacketOffset;
+   int iHciDataSize;
+   ANT_FUNC_START();
+
+   // Keep trying to read while there is an error, and that error is EAGAIN
+   while (((iRxLenRead = read(pstChnlInfo->iFd, &aucRxBuffer[eChannel][iRxBufferLength[eChannel]], (sizeof(aucRxBuffer[eChannel]) - iRxBufferLength[eChannel]))) < 0)
+                   && errno == EAGAIN)
+      ;
+
+   if (iRxLenRead < 0) {
+      if (errno == ENODEV) {
+         ANT_ERROR("%s not enabled, exiting rx thread",
+               pstChnlInfo->pcDevicePath);
+
+         goto out;
+      } else if (errno == ENXIO) {
+         ANT_ERROR("%s there is no physical ANT device connected",
+               pstChnlInfo->pcDevicePath);
+
+         goto out;
+      } else {
+         ANT_ERROR("%s read thread exiting, unhandled error: %s",
+               pstChnlInfo->pcDevicePath, strerror(errno));
+
+         goto out;
+      }
+   } else {
+      ANT_SERIAL(aucRxBuffer[eChannel], iRxLenRead, 'R');
+
+      iRxLenRead += iRxBufferLength[eChannel];   // add existing data on
+
+      // if we didn't get a full packet, then just exit
+      if (iRxLenRead < (aucRxBuffer[eChannel][ANT_HCI_SIZE_OFFSET] + ANT_HCI_HEADER_SIZE + ANT_HCI_FOOTER_SIZE)) {
+         iRxBufferLength[eChannel] = iRxLenRead;
+         iRet = 0;
+         goto out;
+      }
+
+      iRxBufferLength[eChannel] = 0;    // reset buffer length here since we should have a full packet
+
+#if ANT_HCI_OPCODE_SIZE == 1  // Check the different message types by opcode
+      ANT_U8 opcode = aucRxBuffer[eChannel][ANT_HCI_OPCODE_OFFSET];
+
+      if(ANT_HCI_OPCODE_COMMAND_COMPLETE == opcode) {
+         // Command Complete, so signal a FLOW_GO
+         if(setFlowControl(pstChnlInfo, ANT_FLOW_GO)) {
+            goto out;
+         }
+      } else if(ANT_HCI_OPCODE_FLOW_ON == opcode) {
+         // FLow On, so resend the last Tx
+#ifdef ANT_FLOW_RESEND
+         // Check if there is a message to resend
+         if(pstChnlInfo->ucResendMessageLength > 0) {
+            ant_tx_message_flowcontrol_none(eChannel, pstChnlInfo->ucResendMessageLength, pstChnlInfo->pucResendMessage);
+         } else {
+            ANT_DEBUG_D("Resend requested by chip, but tx request cancelled");
+         }
+#endif // ANT_FLOW_RESEND
+      } else if(ANT_HCI_OPCODE_ANT_EVENT == opcode)
+         // ANT Event, send ANT packet to Rx Callback
+#endif // ANT_HCI_OPCODE_SIZE == 1
+      {
+      // Received an ANT packet
+         iCurrentHciPacketOffset = 0;
+
+         while(iCurrentHciPacketOffset < iRxLenRead) {
+
+            // TODO Allow HCI Packet Size value to be larger than 1 byte
+            // This currently works as no size value is greater than 255, and little endian
+            iHciDataSize = aucRxBuffer[eChannel][iCurrentHciPacketOffset + ANT_HCI_SIZE_OFFSET];
+
+            if ((iHciDataSize + ANT_HCI_HEADER_SIZE + ANT_HCI_FOOTER_SIZE + iCurrentHciPacketOffset) >
+                  iRxLenRead) {
+               // we don't have a whole packet
+               iRxBufferLength[eChannel] = iRxLenRead - iCurrentHciPacketOffset;
+               memcpy(aucRxBuffer[eChannel], &aucRxBuffer[eChannel][iCurrentHciPacketOffset], iRxBufferLength[eChannel]);
+               // the increment at the end should push us out of the while loop
+            } else
+#ifdef ANT_MESG_FLOW_CONTROL
+            if (aucRxBuffer[eChannel][iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET + ANT_MSG_ID_OFFSET] ==
+                  ANT_MESG_FLOW_CONTROL) {
+               // This is a flow control packet, not a standard ANT message
+               if(setFlowControl(pstChnlInfo, \
+                     aucRxBuffer[eChannel][iCurrentHciPacketOffset + ANT_HCI_DATA_OFFSET + ANT_MSG_DATA_OFFSET])) {
+                  goto out;
+               }
+            } else
+#endif // ANT_MESG_FLOW_CONTROL
+            {
+               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]);
+               } else {
+                  ANT_WARN("%s rx callback is null", pstChnlInfo->pcDevicePath);
+               }
+            }
+
+            iCurrentHciPacketOffset = iCurrentHciPacketOffset + ANT_HCI_HEADER_SIZE + ANT_HCI_FOOTER_SIZE + iHciDataSize;
+         }
+      }
+
+      iRet = 0;
+   }
+
+out:
+   ANT_FUNC_END();
+   return iRet;
+}
diff --git a/src/bt-vendor_vfs/inc/ant_hci_defines.h b/src/bt-vendor_vfs/inc/ant_hci_defines.h
new file mode 100644
index 0000000..3ffe672
--- /dev/null
+++ b/src/bt-vendor_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/bt-vendor_vfs/inc/ant_rx_chardev.h b/src/bt-vendor_vfs/inc/ant_rx_chardev.h
new file mode 100644
index 0000000..1024dac
--- /dev/null
+++ b/src/bt-vendor_vfs/inc/ant_rx_chardev.h
@@ -0,0 +1,98 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2011 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_rx_chardev.h
+*
+*   BRIEF:
+*      This file defines the receive thread function, the ant_rx_thread_info_t
+*      type for storing the -configuration- <state> of the receive thread, the
+*      ant_channel_info_t type for storing a channel's (transport path)
+*      configuration, and an enumeration of all ANT channels (transport paths).
+*
+*
+\*******************************************************************************/
+
+#ifndef __ANT_RX_NATIVE_H
+#define __ANT_RX_NATIVE_H
+
+#include "ant_native.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
+
+#define ANT_MSG_SIZE_OFFSET     ((ANT_U8)0)
+#define ANT_MSG_ID_OFFSET       ((ANT_U8)1)
+#define ANT_MSG_DATA_OFFSET     ((ANT_U8)2)
+
+/* This struct defines the info passed to an rx thread */
+typedef struct {
+   /* Device path */
+   const char *pcDevicePath;
+   /* File descriptor to read from */
+   int iFd;
+   /* Callback to call with ANT packet */
+   ANTNativeANTEventCb fnRxCallback;
+   /* Flow control response if channel supports it */
+   ANT_U8 ucFlowControlResp;
+   /* Handle to flow control condition */
+   pthread_cond_t *pstFlowControlCond;
+   /* Handle to flow control mutex */
+   pthread_mutex_t *pstFlowControlLock;
+#ifdef ANT_FLOW_RESEND
+   /* Length of message to resend on request from chip */
+   ANT_U8 ucResendMessageLength;
+   /* The message to resend on request from chip */
+   ANT_U8 *pucResendMessage;
+#endif // ANT_FLOW_RESEND
+} ant_channel_info_t;
+
+typedef enum {
+#ifdef ANT_DEVICE_NAME // Single transport path
+   SINGLE_CHANNEL,
+#else // Separate data/command paths
+   DATA_CHANNEL,
+   COMMAND_CHANNEL,
+#endif // Separate data/command paths
+   NUM_ANT_CHANNELS
+} ant_channel_type;
+
+typedef struct {
+   /* Thread handle */
+   pthread_t stRxThread;
+   /* Exit condition */
+   ANT_U8 ucRunThread;
+   /* Set state as resetting override */
+   ANT_U8 ucChipResetting;
+   /* Handle to state change lock for crash cleanup */
+   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.
+
+/* This is the rx thread function. It loops reading ANT packets until told to
+ * exit */
+void *fnRxThread(void *ant_rx_thread_info);
+
+#endif /* ifndef __ANT_RX_NATIVE_H */
+
diff --git a/src/bt-vendor_vfs/inc/antradio_power.h b/src/bt-vendor_vfs/inc/antradio_power.h
new file mode 100644
index 0000000..1aa0b24
--- /dev/null
+++ b/src/bt-vendor_vfs/inc/antradio_power.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef __ANTRADIOPM_H
+#define __ANTRADIOPM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enable the ANT radio interface.
+ *
+ * Responsible for power on, and bringing up HCI interface.
+ * Will block until the HCI interface is ready to use.
+ *
+ * Returns 0 on success, -ve on error */
+int ant_enable();
+
+/* Disable the ANT radio interface.
+ *
+ * Responsbile for pulling down the HCI interface, and powering down the chip.
+ * Will block until power down is complete, and it is safe to immediately call 
+ * enable().
+ *
+ * Returns 0 on success, -ve on error */
+int ant_disable();
+
+/* Returns 1 if enabled, 0 if disabled, and -ve on error */
+int ant_is_enabled();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/bt-vendor_vfs/qualcomm/uart/ant_driver_defines.h b/src/bt-vendor_vfs/qualcomm/uart/ant_driver_defines.h
new file mode 100644
index 0000000..06b2e22
--- /dev/null
+++ b/src/bt-vendor_vfs/qualcomm/uart/ant_driver_defines.h
@@ -0,0 +1,98 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2011 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_driver_defines.h
+*
+*   BRIEF:
+*      This file defines ANT specific HCI values used by the ANT chip for a
+*      Qualcomm UART implementation.
+*
+*
+\*******************************************************************************/
+
+#ifndef __VFS_PRERELEASE_H
+#define __VFS_PRERELEASE_H
+
+// Packets may be prefixed with an optional packet type byte when being sent to
+// the chip. Will not be present in messages received.
+
+// -----------------------------------------
+// |         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.
+
+
+// ---------------------- REQUIRED
+
+// Which chip is this library being built for:
+#define ANT_CHIP_NAME                        "Qualcomm UART"
+
+// Set the file name the driver creates for the ANT device:
+//   If chip uses separate command and data paths:
+// #define ANT_COMMANDS_DEVICE_NAME             "/dev/X"
+// #define ANT_DATA_DEVICE_NAME                 "/dev/Y"
+// OR
+//   If chip uses one path:
+
+#define ANT_DEVICE_NAME                          "/dev/ttyHS0"
+
+// Optional Packet prefix byte.
+#define HCI_PACKET_TYPE_SIZE                 1
+
+// Set to the number of bytes of header is for Opcode:
+#define ANT_HCI_OPCODE_SIZE                  0
+
+// Set to the number of bytes of header is for Data Size:
+#define ANT_HCI_SIZE_SIZE                    1
+
+// Set to the number of bytes of header is for Sync:
+#define ANT_HCI_SYNC_SIZE                    0
+
+// Set to the number of bytes of footer is for Checksum:
+#define ANT_HCI_CHECKSUM_SIZE                0
+
+// ---------------------- OPTIONAL
+
+// If hard reset is supported, define ANT_IOCTL_RESET
+// #define ANT_IOCTL_RESET                      _IOW('U', 210, int)
+// #define ANT_IOCTL_RESET_PARAMETER            (0)
+
+// If the chip sends flow control messages:
+//  Define the Opcode for a Flow Control message:
+#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)
+// AND
+//   define the message content:
+//     That signals Flow Go:
+#define ANT_FLOW_GO                          ((ANT_U8)0x00)
+
+//     That signals Flow Stop:
+#define ANT_FLOW_STOP                        ((ANT_U8)0x80)
+
+// Define protocol byte to be added
+// as multiple data will be sent/received over
+// same transport(BT, ANT ..etc)
+// needed for HCI_PACKET_TYPE_SIZE > 1.
+#define ANT_CMD_TYPE_PACKET                  ((ANT_U8)0x0C)
+#define ANT_DATA_TYPE_PACKET                 ((ANT_U8)0x0E)
+
+#endif /* ifndef __VFS_PRERELEASE_H */
diff --git a/src/common/inc/ant_version.h b/src/common/inc/ant_version.h
index a682134..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 "0"

+#define LIBANT_STACK_INCRE "2"

 

 #endif // __ANT_VERSION_H

 

diff --git a/src/vfs/Android.mk b/src/vfs/Android.mk
index 92ea171..3d0af04 100644
--- a/src/vfs/Android.mk
+++ b/src/vfs/Android.mk
@@ -26,6 +26,10 @@
 LOCAL_C_INCLUDES += \

    $(LOCAL_PATH)/$(ANT_DIR)/ste/cg29xx \

 

+else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"qualcomm-smd")

+LOCAL_C_INCLUDES += \

+   $(LOCAL_PATH)/$(ANT_DIR)/qualcomm/smd \

+

 else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"vfs-prerelease")

 LOCAL_C_INCLUDES += \

    $(LOCAL_PATH)/$(ANT_DIR)/prerelease \

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_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 @@
 //      -
 //
 //  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 @@
    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 @@
 ////////////////////////////////////////////////////////////////////
 //  ant_deinit
 //
-//  Doesn't actually do anything.
+//  clean up eventfd object
 //
 //  Parameters:
 //      -
@@ -123,7 +138,12 @@
    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 @@
    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 @@
 
    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 @@
       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 2f0cc33..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()
@@ -53,9 +54,38 @@
 	static int iRxBufferLength[NUM_ANT_CHANNELS] = {0, 0};
 #endif // 
 
+// Defines for use with the poll() call
+#define EVENT_DATA_AVAILABLE (POLLIN|POLLRDNORM)
+#define EVENT_DISABLE (POLLHUP)
+#define EVENT_HARD_RESET (POLLERR|POLLPRI|POLLRDHUP)
+
+#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);
 
 /*
+ * Function to check that all given flags are set in a particular value.
+ * Designed for use with the revents field of pollfds filled out by poll().
+ *
+ * Parameters:
+ *    - value: The value that will be checked to contain all flags.
+ *    - flags: Bitwise-or of the flags that value should be checked for.
+ *
+ * Returns:
+ *    - true IFF all the bits that are set in 'flags' are also set in 'value'
+ */
+ANT_BOOL areAllFlagsSet(short value, short flags)
+{
+   value &= flags;
+   return (value == flags);
+}
+
+/*
  * This thread waits for ANT messages from a VFS file.
  */
 void *fnRxThread(void *ant_rx_thread_info)
@@ -63,67 +93,97 @@
    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();
 
    stRxThreadInfo = (ant_rx_thread_info_t *)ant_rx_thread_info;
    for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
       astPollFd[eChannel].fd = stRxThreadInfo->astChannels[eChannel].iFd;
-      astPollFd[eChannel].events = POLLIN | POLLRDNORM;
+      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 (astPollFd[eChannel].revents & (POLLERR | POLLPRI | POLLRDHUP)) {
-               ANT_ERROR("poll error from %s. exiting rx thread",
+            if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_HARD_RESET)) {
+               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;
+               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(
+                     "poll hang-up from %s. exiting rx thread", stRxThreadInfo->astChannels[eChannel].pcDevicePath);
 
-               if (g_fnStateCallback) {
-                  g_fnStateCallback(RADIO_STATUS_RESETTING);
-               }
+               // set flag to exit out of Rx Loop
+               stRxThreadInfo->ucRunThread = 0;
 
-               goto reset;
-            } else if (astPollFd[eChannel].revents & (POLLIN | POLLRDNORM)) {
+            } else if (areAllFlagsSet(astPollFd[eChannel].revents, EVENT_DATA_AVAILABLE)) {
                ANT_DEBUG_D("data on %s. reading it",
                             stRxThreadInfo->astChannels[eChannel].pcDevicePath);
 
                if (readChannelMsg(eChannel, &stRxThreadInfo->astChannels[eChannel]) < 0) {
-                  goto out;
+                  // 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;
+         }
       }
    }
 
-out:
-   stRxThreadInfo->ucRunThread = 0;
-
-   /* Try to get stEnabledStatusLock.
-    * if you get it then noone is enabling or disabling
-    * if you can't get it assume something made you exit */
+   /* disable ANT radio if not already disabling */
+   // Try to get stEnabledStatusLock.
+   // if you get it then no one is enabling or disabling
+   // if you can't get it assume something made you exit
    ANT_DEBUG_V("try getting stEnabledStatusLock in %s", __FUNCTION__);
    iMutexLockResult = pthread_mutex_trylock(stRxThreadInfo->pstEnabledStatusLock);
    if (!iMutexLockResult) {
       ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);
       ANT_WARN("rx thread has unexpectedly crashed, cleaning up");
-      stRxThreadInfo->stRxThread = 0; /* spoof our handle as closed so we don't
-                                       * try to join ourselves in disable */
+
+      // spoof our handle as closed so we don't try to join ourselves in disable
+      stRxThreadInfo->stRxThread = 0;
 
       if (g_fnStateCallback) {
          g_fnStateCallback(RADIO_STATUS_DISABLING);
@@ -145,15 +205,26 @@
       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
+}
 
-reset:
+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);
+   }
+
    stRxThreadInfo->ucRunThread = 0;
 
    ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
@@ -188,9 +259,6 @@
    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..a3481b0 100644
--- a/src/vfs/inc/ant_rx_chardev.h
+++ b/src/vfs/inc/ant_rx_chardev.h
@@ -1,96 +1,98 @@
-/*
- * ANT Stack
- *
- * Copyright 2011 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_rx_chardev.h
-*
-*   BRIEF:
-*      This file defines the receive thread function, the ant_rx_thread_info_t
-*      type for storing the -configuration- <state> of the receive thread, the
-*      ant_channel_info_t type for storing a channel's (transport path)
-*      configuration, and an enumeration of all ANT channels (transport paths).
-*
-*
-\*******************************************************************************/
-
-#ifndef __ANT_RX_NATIVE_H
-#define __ANT_RX_NATIVE_H
-
-#include "ant_native.h"
-#include "ant_driver_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
-
-#define ANT_MSG_SIZE_OFFSET     ((ANT_U8)0)
-#define ANT_MSG_ID_OFFSET       ((ANT_U8)1)
-#define ANT_MSG_DATA_OFFSET     ((ANT_U8)2)
-
-/* This struct defines the info passed to an rx thread */
-typedef struct {
-   /* Device path */
-   const char *pcDevicePath;
-   /* File descriptor to read from */
-   int iFd;
-   /* Callback to call with ANT packet */
-   ANTNativeANTEventCb fnRxCallback;
-   /* Flow control response if channel supports it */
-   ANT_U8 ucFlowControlResp;
-   /* Handle to flow control condition */
-   pthread_cond_t *pstFlowControlCond;
-   /* Handle to flow control mutex */
-   pthread_mutex_t *pstFlowControlLock;
-#ifdef ANT_FLOW_RESEND
-   /* Length of message to resend on request from chip */
-   ANT_U8 ucResendMessageLength;
-   /* The message to resend on request from chip */
-   ANT_U8 *pucResendMessage;
-#endif // ANT_FLOW_RESEND
-} ant_channel_info_t;
-
-typedef enum {
-#ifdef ANT_DEVICE_NAME // Single transport path
-   SINGLE_CHANNEL,
-#else // Separate data/command paths
-   DATA_CHANNEL,
-   COMMAND_CHANNEL,
-#endif // Separate data/command paths
-   NUM_ANT_CHANNELS
-} ant_channel_type;
-
-typedef struct {
-   /* Thread handle */
-   pthread_t stRxThread;
-   /* Exit condition */
-   ANT_U8 ucRunThread;
-   /* Set state as resetting override */
-   ANT_U8 ucChipResetting;
-   /* Handle to state change lock for crash cleanup */
-   pthread_mutex_t *pstEnabledStatusLock;
-   /* ANT channels */
-   ant_channel_info_t astChannels[NUM_ANT_CHANNELS];
-} ant_rx_thread_info_t;
-
-extern ANTNativeANTStateCb g_fnStateCallback;  // TODO State callback should be inside ant_rx_thread_info_t.
-
-/* This is the rx thread function. It loops reading ANT packets until told to
- * exit */
-void *fnRxThread(void *ant_rx_thread_info);
-
-#endif /* ifndef __ANT_RX_NATIVE_H */
-
+/*

+ * ANT Stack

+ *

+ * Copyright 2011 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_rx_chardev.h

+*

+*   BRIEF:

+*      This file defines the receive thread function, the ant_rx_thread_info_t

+*      type for storing the -configuration- <state> of the receive thread, the

+*      ant_channel_info_t type for storing a channel's (transport path)

+*      configuration, and an enumeration of all ANT channels (transport paths).

+*

+*

+\*******************************************************************************/

+

+#ifndef __ANT_RX_NATIVE_H

+#define __ANT_RX_NATIVE_H

+

+#include "ant_native.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

+

+#define ANT_MSG_SIZE_OFFSET     ((ANT_U8)0)

+#define ANT_MSG_ID_OFFSET       ((ANT_U8)1)

+#define ANT_MSG_DATA_OFFSET     ((ANT_U8)2)

+

+/* This struct defines the info passed to an rx thread */

+typedef struct {

+   /* Device path */

+   const char *pcDevicePath;

+   /* File descriptor to read from */

+   int iFd;

+   /* Callback to call with ANT packet */

+   ANTNativeANTEventCb fnRxCallback;

+   /* Flow control response if channel supports it */

+   ANT_U8 ucFlowControlResp;

+   /* Handle to flow control condition */

+   pthread_cond_t *pstFlowControlCond;

+   /* Handle to flow control mutex */

+   pthread_mutex_t *pstFlowControlLock;

+#ifdef ANT_FLOW_RESEND

+   /* Length of message to resend on request from chip */

+   ANT_U8 ucResendMessageLength;

+   /* The message to resend on request from chip */

+   ANT_U8 *pucResendMessage;

+#endif // ANT_FLOW_RESEND

+} ant_channel_info_t;

+

+typedef enum {

+#ifdef ANT_DEVICE_NAME // Single transport path

+   SINGLE_CHANNEL,

+#else // Separate data/command paths

+   DATA_CHANNEL,

+   COMMAND_CHANNEL,

+#endif // Separate data/command paths

+   NUM_ANT_CHANNELS

+} ant_channel_type;

+

+typedef struct {

+   /* Thread handle */

+   pthread_t stRxThread;

+   /* Exit condition */

+   ANT_U8 ucRunThread;

+   /* Set state as resetting override */

+   ANT_U8 ucChipResetting;

+   /* Handle to state change lock for crash cleanup */

+   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.

+

+/* This is the rx thread function. It loops reading ANT packets until told to

+ * exit */

+void *fnRxThread(void *ant_rx_thread_info);

+

+#endif /* ifndef __ANT_RX_NATIVE_H */

+

diff --git a/src/vfs/prerelease/ant_driver_defines.h b/src/vfs/prerelease/ant_driver_defines.h
index f2e843b..c30c6e4 100644
--- a/src/vfs/prerelease/ant_driver_defines.h
+++ b/src/vfs/prerelease/ant_driver_defines.h
@@ -1,98 +1,85 @@
-/*
- * ANT Stack
- *
- * Copyright 2011 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_driver_defines.h
-*
-*   BRIEF:
-*      This file defines ANT specific HCI values used by the ANT chip for a
-*      sample TTY implementation.
-*
-*
-\*******************************************************************************/
-
-#ifndef __VFS_PRERELEASE_H
-#define __VFS_PRERELEASE_H
-
-// -----------------------------------------
-// |         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.
-
-
-// ---------------------- REQUIRED
-
-// Which chip is this library being built for:
-#define ANT_CHIP_NAME                        "TTY"
-
-// Set the file name the driver creates for the ANT device:
-//   If chip uses separate command and data paths:
-#define ANT_COMMANDS_DEVICE_NAME             "/dev/smd5"
-#define ANT_DATA_DEVICE_NAME                 "/dev/smd6"
-// OR
-//   If chip uses one path:
-// #define ANT_DEVICE_NAME                      "/dev/Z"
-
-	
-// Set to the number of bytes of header is for Opcode:
-#define ANT_HCI_OPCODE_SIZE                  0
- 	
-// Set to the number of bytes of header is for Data Size:
-#define ANT_HCI_SIZE_SIZE                    1
- 	
-// Set to the number of bytes of header is for Sync:
-#define ANT_HCI_SYNC_SIZE                    0
- 	
-// Set to the number of bytes of footer is for Checksum:
-#define ANT_HCI_CHECKSUM_SIZE                0
- 	
-// ---------------------- OPTIONAL
-
-// If hard reset is supported, define ANT_IOCTL_RESET
-// #define ANT_IOCTL_RESET                      _IOW('U', 210, int)
-// #define ANT_IOCTL_RESET_PARAMETER            (0)
-
-// If the chip sends flow control messages:
-//  Define the Opcode for a Flow Control message:
-#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)
-// AND
-//   define the message content:
-//     That signals Flow Go:
-#define ANT_FLOW_GO                          ((ANT_U8)0x00)
- 	
-//     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 */
+/*

+ * ANT Stack

+ *

+ * Copyright 2011 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_driver_defines.h

+*

+*   BRIEF:

+*      This file defines ANT specific HCI values used by the ANT chip for a

+*      sample TTY implementation.

+*

+*

+\*******************************************************************************/

+

+#ifndef __VFS_PRERELEASE_H

+#define __VFS_PRERELEASE_H

+

+// -----------------------------------------

+// |         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.

+

+

+// ---------------------- REQUIRED

+

+// Which chip is this library being built for:

+#define ANT_CHIP_NAME                        "TTY"

+

+// Set the file name the driver creates for the ANT device:

+//   If chip uses separate command and data paths:

+#define ANT_COMMANDS_DEVICE_NAME             "/dev/smd5"

+#define ANT_DATA_DEVICE_NAME                 "/dev/smd6"

+// OR

+//   If chip uses one path:

+// #define ANT_DEVICE_NAME                      "/dev/Z"

+

+	

+// Set to the number of bytes of header is for Opcode:

+#define ANT_HCI_OPCODE_SIZE                  0

+ 	

+// Set to the number of bytes of header is for Data Size:

+#define ANT_HCI_SIZE_SIZE                    1

+ 	

+// Set to the number of bytes of header is for Sync:

+#define ANT_HCI_SYNC_SIZE                    0

+ 	

+// Set to the number of bytes of footer is for Checksum:

+#define ANT_HCI_CHECKSUM_SIZE                0

+ 	

+// ---------------------- OPTIONAL

+

+// If hard reset is supported, define ANT_IOCTL_RESET

+// #define ANT_IOCTL_RESET                      _IOW('U', 210, int)

+// #define ANT_IOCTL_RESET_PARAMETER            (0)

+

+// If the chip sends flow control messages:

+//  Define the Opcode for a Flow Control message:

+#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)

+// AND

+//   define the message content:

+//     That signals Flow Go:

+#define ANT_FLOW_GO                          ((ANT_U8)0x00)

+ 	

+//     That signals Flow Stop:

+#define ANT_FLOW_STOP                        ((ANT_U8)0x80)

+

+#endif /* ifndef __VFS_PRERELEASE_H */

diff --git a/src/vfs/qualcomm/smd/ant_driver_defines.h b/src/vfs/qualcomm/smd/ant_driver_defines.h
new file mode 100644
index 0000000..273286d
--- /dev/null
+++ b/src/vfs/qualcomm/smd/ant_driver_defines.h
@@ -0,0 +1,85 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2011 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_driver_defines.h
+*
+*   BRIEF:
+*      This file defines ANT specific HCI values used by the ANT chip for a
+*      sample TTY implementation.
+*
+*
+\*******************************************************************************/
+
+#ifndef __VFS_PRERELEASE_H
+#define __VFS_PRERELEASE_H
+
+// -----------------------------------------
+// |         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.
+
+
+// ---------------------- REQUIRED
+
+// Which chip is this library being built for:
+#define ANT_CHIP_NAME                        "Qualcomm SMD"
+
+// Set the file name the driver creates for the ANT device:
+//   If chip uses separate command and data paths:
+#define ANT_COMMANDS_DEVICE_NAME             "/dev/smd5"
+#define ANT_DATA_DEVICE_NAME                 "/dev/smd6"
+// OR
+//   If chip uses one path:
+// #define ANT_DEVICE_NAME                      "/dev/Z"
+
+	
+// Set to the number of bytes of header is for Opcode:
+#define ANT_HCI_OPCODE_SIZE                  0
+ 	
+// Set to the number of bytes of header is for Data Size:
+#define ANT_HCI_SIZE_SIZE                    1
+ 	
+// Set to the number of bytes of header is for Sync:
+#define ANT_HCI_SYNC_SIZE                    0
+ 	
+// Set to the number of bytes of footer is for Checksum:
+#define ANT_HCI_CHECKSUM_SIZE                0
+ 	
+// ---------------------- OPTIONAL
+
+// If hard reset is supported, define ANT_IOCTL_RESET
+// #define ANT_IOCTL_RESET                      _IOW('U', 210, int)
+// #define ANT_IOCTL_RESET_PARAMETER            (0)
+
+// If the chip sends flow control messages:
+//  Define the Opcode for a Flow Control message:
+#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)
+// AND
+//   define the message content:
+//     That signals Flow Go:
+#define ANT_FLOW_GO                          ((ANT_U8)0x00)
+ 	
+//     That signals Flow Stop:
+#define ANT_FLOW_STOP                        ((ANT_U8)0x80)
+
+#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 */