Broke Android_System_package in to individual repositories
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..801a40c
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2009 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.
+#
+
+ifneq ($(BOARD_ANT_WIRELESS_DEVICE),)
+
+#
+# ANT native library
+#
+
+include $(CLEAR_VARS)
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"wl12xx")
+
+include $(LOCAL_PATH)/hal/bluez_hci/Android.mk
+
+else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"chip-B")
+
+include $(LOCAL_PATH)/hal/chip-B/Android.mk
+
+else ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"chip-C")
+
+include $(LOCAL_PATH)/hal/chip-C/Android.mk
+
+else
+
+$(error Unsupported BOARD_ANT_WIRELESS_DEVICE := $(BOARD_ANT_WIRELESS_DEVICE))
+
+endif # BOARD_ANT_WIRELESS_DEVICE type
+
+
+#
+# ANT Application
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/src/common/inc \
+	$(LOCAL_PATH)/app
+
+LOCAL_CFLAGS:= -g -c -W -Wall -O2
+
+LOCAL_SRC_FILES:= \
+	$(LOCAL_PATH)/app/ant_app.c
+
+LOCAL_SHARED_LIBRARIES := \
+	libantradio \
+	libcutils
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE:=antradio_app
+
+include $(BUILD_EXECUTABLE)
+
+
+endif # BOARD_ANT_WIRELESS_DEVICE defined
diff --git a/JAntNative.cpp b/JAntNative.cpp
new file mode 100644
index 0000000..2e3beb0
--- /dev/null
+++ b/JAntNative.cpp
@@ -0,0 +1,366 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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:     JAntNative.cpp
+*
+*   BRIEF:
+*      This file provides the implementation of the native interface functions for ANT
+*
+*
+\*******************************************************************************/
+
+#include "android_runtime/AndroidRuntime.h"
+#include "jni.h"
+#include "nativehelper/JNIHelp.h"
+
+static JNIEnv *g_jEnv = NULL;
+static JavaVM *g_jVM = NULL;
+static jclass g_sJClazz;
+static jmethodID g_sMethodId_nativeCb_AntRxMessage;
+static jmethodID g_sMethodId_nativeCb_AntStateChange;
+
+extern "C"
+{
+   #include "ant_native.h"
+   #include "ant_log.h"
+   #undef LOG_TAG
+   #define LOG_TAG "JAntNative"
+
+   void nativeJAnt_RxCallback(ANT_U8 ucLen, ANT_U8* pucData);
+   void nativeJAnt_StateCallback(ANTRadioEnabledStatus uiNewState);
+}
+
+static jint nativeJAnt_Create(JNIEnv *env, jobject obj)
+{
+   ANTStatus antStatus = ANT_STATUS_FAILED;
+   (void)env; //unused warning
+   (void)obj; //unused warning
+
+   ANT_FUNC_START();
+
+   antStatus = ant_init();
+   if (antStatus)
+   {
+      ANT_DEBUG_D("failed to init ANT stack");
+      goto CLEANUP;
+   }
+
+   antStatus = set_ant_rx_callback(nativeJAnt_RxCallback);
+   if (antStatus)
+   {
+      ANT_DEBUG_D("failed to set ANT rx callback");
+      goto CLEANUP;
+   }
+
+   antStatus = set_ant_state_callback(nativeJAnt_StateCallback);
+   if (antStatus)
+   {
+      ANT_DEBUG_D("failed to set ANT state callback");
+      goto CLEANUP;
+   }
+
+CLEANUP:
+   ANT_FUNC_END();
+   return antStatus;
+}
+
+static jint nativeJAnt_Destroy(JNIEnv *env, jobject obj)
+{
+   (void)env; //unused warning
+   (void)obj; //unused warning
+   ANTStatus status;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_D("nativeJAnt_Destroy(): calling ant_deinit");
+   status = ant_deinit();
+   if (status)
+   {
+      ANT_DEBUG_D("failed to deinit ANT stack returned %d",(int)status);
+      return status;
+   }
+   else
+   {
+      ANT_DEBUG_D("deinit ANT stack Success");
+   }
+
+   ANT_FUNC_END();
+   return status;
+}
+
+static jint nativeJAnt_Enable(JNIEnv *env, jobject obj)
+{
+   (void)env; //unused warning
+   (void)obj; //unused warning
+   ANT_FUNC_START();
+
+   ANTStatus status = ant_enable_radio();
+
+   ANT_FUNC_END();
+   return status;
+}
+
+static jint nativeJAnt_Disable(JNIEnv *env, jobject obj)
+{
+   (void)env; //unused warning
+   (void)obj; //unused warning
+   ANT_FUNC_START();
+
+   ANTStatus status = ant_disable_radio();
+
+   ANT_FUNC_END();
+   return status;
+}
+
+static jint nativeJAnt_GetRadioEnabledStatus(JNIEnv *env, jobject obj)
+{
+   (void)env; //unused warning
+   (void)obj; //unused warning
+   ANT_FUNC_START();
+
+   jint status = ant_radio_enabled_status();
+
+   ANT_FUNC_END();
+   return status;
+}
+
+static jint nativeJAnt_TxMessage(JNIEnv *env, jobject obj, jbyteArray msg)
+{
+   (void)obj; //unused warning
+   ANT_FUNC_START();
+
+   if (msg == NULL)
+   {
+      if (jniThrowException(env, "java/lang/NullPointerException", NULL))
+      {
+         ANT_ERROR("Unable to throw NullPointerException");
+      }
+      return -1;
+   }
+
+   jbyte* msgBytes = env->GetByteArrayElements(msg, NULL);
+   jint msgLength = env->GetArrayLength(msg);
+
+   ANTStatus status = ant_tx_message((ANT_U8) msgLength, (ANT_U8 *)msgBytes);
+   ANT_DEBUG_D("nativeJAnt_TxMessage: ant_tx_message() returned %d", (int)status);
+
+   env->ReleaseByteArrayElements(msg, msgBytes, JNI_ABORT);
+
+   ANT_FUNC_END();
+   return status;
+}
+
+static jint nativeJAnt_HardReset(JNIEnv *env, jobject obj)
+{
+   (void)env; //unused warning
+   (void)obj; //unused warning
+   ANT_FUNC_START();
+
+   ANTStatus status = ant_radio_hard_reset();
+
+   ANT_FUNC_END();
+   return status;
+}
+
+extern "C"
+{
+
+   /**********************************************************************
+    *                              Callback registration
+    ***********************************************************************/
+   void nativeJAnt_RxCallback(ANT_U8 ucLen, ANT_U8* pucData)
+   {
+      JNIEnv* env = NULL;
+      jbyteArray jAntRxMsg = NULL;
+      ANT_FUNC_START();
+
+      ANT_DEBUG_D( "got message %d bytes", ucLen);
+
+      g_jVM->AttachCurrentThread((&env), NULL);
+
+      if (env == NULL)
+      {
+         ANT_DEBUG_D("nativeJAnt_RxCallback: Entered, env is null");
+         return; // log error? cleanup?
+      }
+      else
+      {
+         ANT_DEBUG_D("nativeJAnt_RxCallback: jEnv %p", env);
+      }
+
+      jAntRxMsg = env->NewByteArray(ucLen);
+
+      if (jAntRxMsg == NULL)
+      {
+         ANT_ERROR("nativeJAnt_RxCallback: Failed creating java byte[]");
+         goto CLEANUP;
+      }
+
+      env->SetByteArrayRegion(jAntRxMsg,0,ucLen,(jbyte*)pucData);
+
+      if (env->ExceptionOccurred())
+      {
+         ANT_ERROR("nativeJAnt_RxCallback: ExceptionOccurred during byte[] copy");
+         goto CLEANUP;
+      }
+      ANT_DEBUG_V("nativeJAnt_RxCallback: Calling java rx callback");
+      env->CallStaticVoidMethod(g_sJClazz, g_sMethodId_nativeCb_AntRxMessage, jAntRxMsg);
+      ANT_DEBUG_V("nativeJAnt_RxCallback: Called java rx callback");
+
+      if (env->ExceptionOccurred())
+      {
+         ANT_ERROR("nativeJAnt_RxCallback: Calling Java nativeCb_AntRxMessage failed");
+         goto CLEANUP;
+      }
+
+      //Delete the local references
+      if (jAntRxMsg != NULL)
+      {
+         env->DeleteLocalRef(jAntRxMsg);
+      }
+
+      ANT_DEBUG_D("nativeJAnt_RxCallback: Exiting, Calling DetachCurrentThread at the END");
+
+      g_jVM->DetachCurrentThread();
+
+      ANT_FUNC_END();
+      return;
+
+   CLEANUP:
+      ANT_ERROR("nativeJAnt_RxCallback: Exiting due to failure");
+      if (jAntRxMsg != NULL)
+      {
+         env->DeleteLocalRef(jAntRxMsg);
+      }
+
+      if (env->ExceptionOccurred())
+      {
+         env->ExceptionDescribe();
+         env->ExceptionClear();
+      }
+
+      g_jVM->DetachCurrentThread();
+
+      return;
+   }
+
+   void nativeJAnt_StateCallback(ANTRadioEnabledStatus uiNewState)
+   {
+      JNIEnv* env = NULL;
+      jint jNewState = uiNewState;
+      ANT_BOOL iShouldDetach = ANT_FALSE;
+      ANT_FUNC_START();
+
+      g_jVM->GetEnv((void**) &env, JNI_VERSION_1_4);
+      if (env == NULL)
+      {
+         ANT_DEBUG_D("nativeJAnt_StateCallback: called from rx thread, attaching to VM");
+         g_jVM->AttachCurrentThread((&env), NULL);
+         if (env == NULL)
+         {
+            ANT_DEBUG_E("nativeJAnt_StateCallback: failed to attach rx thread to VM");
+            return;
+         }
+         iShouldDetach = ANT_TRUE;
+      }
+      else
+      {
+         ANT_DEBUG_D("nativeJAnt_StateCallback: called from java enable/disable"
+                         ", already attached, don't detach");
+      }
+
+      ANT_DEBUG_V("nativeJAnt_StateCallback: Calling java state callback");
+      env->CallStaticVoidMethod(g_sJClazz, g_sMethodId_nativeCb_AntStateChange, jNewState);
+      ANT_DEBUG_V("nativeJAnt_StateCallback: Called java state callback");
+
+      if (env->ExceptionOccurred())
+      {
+         ANT_ERROR("nativeJAnt_StateCallback: Calling Java nativeCb_AntStateChange failed");
+         env->ExceptionDescribe();
+         env->ExceptionClear();
+      }
+
+      if (iShouldDetach)
+      {
+         ANT_DEBUG_D("nativeJAnt_StateCallback: env was attached, detaching");
+         g_jVM->DetachCurrentThread();
+      }
+
+      ANT_FUNC_END();
+      return;
+   }
+}
+
+static JNINativeMethod g_sMethods[] =
+{
+   /* name, signature, funcPtr */
+   {"nativeJAnt_Create", "()I", (void*)nativeJAnt_Create},
+   {"nativeJAnt_Destroy", "()I", (void*)nativeJAnt_Destroy},
+   {"nativeJAnt_Enable", "()I", (void*)nativeJAnt_Enable},
+   {"nativeJAnt_Disable", "()I", (void*)nativeJAnt_Disable},
+   {"nativeJAnt_GetRadioEnabledStatus", "()I", (void*)nativeJAnt_GetRadioEnabledStatus},
+   {"nativeJAnt_TxMessage","([B)I", (void*)nativeJAnt_TxMessage},
+   {"nativeJAnt_HardReset", "()I", (void *)nativeJAnt_HardReset}
+};
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+   ANT_FUNC_START();
+   (void)reserved; //unused warning
+
+   g_jVM = vm;
+   if (g_jVM->GetEnv((void**) &g_jEnv, JNI_VERSION_1_4) != JNI_OK) {
+      ANT_ERROR("GetEnv failed");
+      return -1;
+   }
+   if (NULL == g_jEnv) {
+      ANT_ERROR("env is null");
+      return -1;
+   }
+
+   g_sJClazz = g_jEnv->FindClass("com/dsi/ant/core/JAntJava");
+   if (NULL == g_sJClazz) {
+      ANT_ERROR("could not find class \"com/dsi/ant/core/JAntJava\"");
+      return -1;
+   }
+
+   /* Save class information in global reference to prevent class unloading */
+   g_sJClazz = (jclass)g_jEnv->NewGlobalRef(g_sJClazz);
+
+   if (g_jEnv->RegisterNatives(g_sJClazz, g_sMethods, NELEM(g_sMethods)) != JNI_OK) {
+      ANT_ERROR("failed to register methods");
+      return -1;
+   }
+
+   g_sMethodId_nativeCb_AntRxMessage = g_jEnv->GetStaticMethodID(g_sJClazz,
+                                             "nativeCb_AntRxMessage", "([B)V");
+   if (NULL == g_sMethodId_nativeCb_AntRxMessage) {
+      ANT_ERROR("VerifyMethodId: Failed getting method id of \"void nativeCb_AntRxMessage(byte[])\"");
+      return -1;
+   }
+
+   g_sMethodId_nativeCb_AntStateChange = g_jEnv->GetStaticMethodID(g_sJClazz,
+                                             "nativeCb_AntStateChange", "(I)V");
+   if (NULL == g_sMethodId_nativeCb_AntStateChange) {
+      ANT_ERROR("VerifyMethodId: Failed getting method id of \"void nativeCb_AntStateChange(int)\"");
+      return -1;
+   }
+
+   ANT_FUNC_END();
+   return JNI_VERSION_1_4;
+}
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..0dafa6b
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,5 @@
+ANT Android System Package
+Copyright 2009-2012 Dynastream Innovations
+
+This product includes software developed at
+Dynastream Innovations (http://www.dynastream.com/).
\ No newline at end of file
diff --git a/README.md b/README.md
index 5d4d917..2d7f30d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
-Linux_commandline-app
+Linux ANT HAL library
 =====================
\ No newline at end of file
diff --git a/app/ant_app.c b/app/ant_app.c
new file mode 100644
index 0000000..b0090ba
--- /dev/null
+++ b/app/ant_app.c
@@ -0,0 +1,326 @@
+/*
+ * ANT Stack testing appication
+ *
+ * Copyright 2009 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.
+ */
+
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <pthread.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <signal.h>
+
+#include "ant_native.h"
+#include "ant_types.h"
+#include "ant_log.h"
+#undef LOG_TAG
+#define LOG_TAG "antradio_app"
+
+/* transient stage */
+typedef ANTStatus ant_status;
+
+void app_ANT_rx_callback(ANT_U8 ucLen, ANT_U8* pucData);
+void app_ANT_state_callback(ANTRadioEnabledStatus uiNewState);
+
+static int Ant_Create(void)
+{
+    ANTStatus antStatus;
+
+    //register_antsig_handlers();
+
+   antStatus = ant_init();
+   if (antStatus)
+   {
+      printf("failed to init ANT rx stacki\n");
+      goto CLEANUP;
+   }
+
+   antStatus = set_ant_rx_callback(app_ANT_rx_callback);
+   if (antStatus)
+   {
+      printf("failed to set ANT rx callback");
+      goto CLEANUP;
+   }
+
+   antStatus = set_ant_state_callback(app_ANT_state_callback);
+   if (antStatus)
+   {
+      printf("failed to set ANT rx callback");
+      goto CLEANUP;
+   }
+   return antStatus;
+
+CLEANUP:
+   return ANT_STATUS_FAILED;
+}
+
+void ProcessCommand(char cCmd)
+{
+   ANT_U8 TxMessage[256];
+   switch (cCmd)
+   {
+      case 'V':
+         TxMessage[0] = 0x02;   //Size
+         TxMessage[1] = 0x4D;   //MESG_REQUEST_ID
+         TxMessage[2] = 0x00;   //Ch0
+         TxMessage[3] = 0x3E;
+         ant_tx_message(4,TxMessage);
+         break;
+      case 'R':
+         TxMessage[0] = 0x01;   //Size
+         TxMessage[1] = 0x4A;   //MESG_RESET_ID
+         TxMessage[2] = 0x00;   //Ch0
+         ant_tx_message(3,TxMessage);
+         break;
+      case 'K':
+         printf("Hard Reset returned: %d\n", ant_radio_hard_reset());
+         break;
+
+      case 'H':
+         //Normally we will not blindly send commands like this and actually check for responses before sending the next command, but this is just for a quick test.
+         ProcessCommand('R');   //Reset chip
+         ProcessCommand('A');   //Assign channel
+         ProcessCommand('F');   //Set RF Freq
+         ProcessCommand('I');   //Set Channel ID
+         ProcessCommand('P');   //Set Channel Period
+         ProcessCommand('O');   //Open Channel
+         break;
+
+      case 'A':
+         TxMessage[0] = 0x03;   //Size
+         TxMessage[1] = 0x42;   //MESG_ASSIGN_ID
+         TxMessage[2] = 0x00;   //Ch0
+         TxMessage[3] = 0x00;   //Assignment Params (Rx channel)
+         TxMessage[4] = 0x01;   //Network 1 (ANT+)
+         ant_tx_message(5,TxMessage);
+         break;
+
+      case 'F':
+         TxMessage[0] = 0x02;   //Size
+         TxMessage[1] = 0x45;   //MESG_CHANNEL_RADIO_FREQ_ID
+         TxMessage[2] = 0x00;   //Ch0
+         TxMessage[3] = 57;   //2.457GHz
+         ant_tx_message(4,TxMessage);
+         break;
+
+      case 'I':
+         TxMessage[0] = 0x05;   //Size
+         TxMessage[1] = 0x51;   //MESG_CHANNEL_ID_ID
+         TxMessage[2] = 0x00;   //Ch0
+         TxMessage[3] = 0x00;   //Wildcard Device Number
+         TxMessage[4] = 0x00;   //Wildcard Device Number
+         TxMessage[5] = 0x78;   //Set HRM Device Type
+         TxMessage[6] = 0x00;   //Wildcard Transmission Type
+         ant_tx_message(7,TxMessage);
+         break;
+
+      case 'P':
+         TxMessage[0] = 0x03;   //Size
+         TxMessage[1] = 0x43;   //MESG_CHANNEL_MESG_PERIOD_ID
+         TxMessage[2] = 0x00;   //Ch0
+         TxMessage[3] = 0x86;   //
+         TxMessage[4] = 0x1F;   // HRM MESG Peroid 0x1F86 (8070)
+         ant_tx_message(5,TxMessage);
+         break;
+
+      case 'O':
+         TxMessage[0] = 0x01;   //Size
+         TxMessage[1] = 0x4B;   //MESG_OPEN_CHANNEL__ID
+         TxMessage[2] = 0x00;   //Ch0
+         ant_tx_message(3,TxMessage);
+         break;
+      case 'E':
+         printf("Enable returned: %d\n", ant_enable_radio());
+         break;
+      case 'D':
+         printf("Disable returned: %d\n", ant_disable_radio());
+         break;
+      case 'S':
+         printf("State is: %d\n", ant_radio_enabled_status());
+         break;
+      case '1':
+         TxMessage[0] = 0x0A;   //Size
+         TxMessage[1] = 0x01;   //Enable
+         TxMessage[2] = 0x00;   //Code upload
+         TxMessage[3] = 0x00;
+         TxMessage[4] = 0x00;
+         TxMessage[5] = 0x00;
+         TxMessage[6] = 0x00;
+         TxMessage[7] = 0x00;
+         TxMessage[8] = 0x00;
+         TxMessage[9] = 0x00;
+         TxMessage[10] = 0x00;
+         //ANT_CORE_Send_VS_Command(0xFDD0, 11, TxMessage);
+         printf("Not Implemented\n");
+         break;
+
+      case '2':
+         TxMessage[0] = 0x00;   //Size
+         //ANT_CORE_Send_VS_Command(0xFF22, 1, TxMessage);
+         printf("Not Implemented\n");
+         break;
+
+
+      case 'X':
+         printf("Exiting\n");
+         break;
+
+      default:
+         printf("Invalid command: %#02x\n", cCmd);
+         break;
+   }
+}
+
+
+void app_ANT_rx_callback(ANT_U8 ucLen, ANT_U8* pucData)
+{
+   ANT_U8 i;
+
+   for(i=0; i <ucLen; i++)
+      printf("[%02X]",pucData[i]);
+   switch (pucData[1])
+   {
+      case 0x3E:
+         printf(" ANT FW Version:%s\n", &(pucData[2]));
+         break;
+      case 0x6F:
+         printf(" Chip Reset\n");
+         break;
+      case 0x40:
+         if (pucData[3] != 0x01)
+         {
+            printf(" Response (Ch:%d Mesg:%02X) ", pucData[2], pucData[3]);
+            if (pucData[4] == 0)
+               printf("Success\n");
+            else
+               printf("Error - %02X\n", pucData[4]);
+         }
+         else
+         {
+            printf(" Event (Ch:%d) %02X\n", pucData[2], pucData[4]);
+         }
+         break;
+      case 0x4E:
+         if (pucData[2] == 0)  //we are using channel 0 for HRM
+         {
+            // We are just assuming this is a HRM message and pulling the BPM out, refer to the ANT+ HRM profile documentation for proper/complete decoding instructions.
+            printf(" BPM: %u\n", pucData[10]);
+         }
+         break;
+
+      default:
+
+         break;
+   }
+   return;
+}
+
+void app_ANT_state_callback(ANTRadioEnabledStatus uiNewState)
+{
+   const char *pcState;
+   switch (uiNewState) {
+   case RADIO_STATUS_UNKNOWN:
+      pcState = "UNKNOWN";
+      break;
+   case RADIO_STATUS_ENABLING:
+      pcState = "ENABLING";
+      break;
+   case RADIO_STATUS_ENABLED:
+      pcState = "ENABLED";
+      break;
+   case RADIO_STATUS_DISABLING:
+      pcState = "DISABLING";
+      break;
+   case RADIO_STATUS_DISABLED:
+      pcState = "DISABLED";
+      break;
+   case RADIO_STATUS_NOT_SUPPORTED:
+      pcState = "NOT SUPPORTED";
+      break;
+   case RADIO_STATUS_SERVICE_NOT_INSTALLED:
+      pcState = "SERVICE NOT INSTALLED";
+      break;
+   case RADIO_STATUS_SERVICE_NOT_CONNECTED:
+      pcState = "SERVICE NOT CONNECTED";
+      break;
+   case RADIO_STATUS_RESETTING:
+      pcState = "RESETTING";
+      break;
+   case RADIO_STATUS_RESET:
+      pcState = "RESET";
+      break;
+   default:
+      printf("State change to: %d is an undefined state\n", uiNewState);
+      return;
+   }
+   printf("State change to: %s\n", pcState);
+}
+
+int main(void)
+{
+   char buffer[1024];
+   int ret = 0;
+
+   if (Ant_Create())
+   {
+      printf("failed to init ANT\n");
+      goto out;
+   }
+
+   printf("===ANT Test===\n");
+   printf("Using libantradio version:\n");
+   printf("%s\n", ant_get_lib_version());
+   printf("\n");
+   printf("Press V to get Version\n");
+   printf("Press R to Reset\n");
+   printf("Press K to hard reset\n");
+   printf("Press H to setup an ANT+ HRM rx channel\n");
+   printf("\n");
+   printf("Press A to Assign channel\n");
+   printf("Press F to set radio Frequency\n");
+   printf("Press I to set channel Id\n");
+   printf("Press P to set channel Peroid\n");
+   printf("Press O to Open channel\n");
+   printf("\n");
+   printf("Press E to Enable ANT\n");
+   printf("Press D to Disable ANT\n");
+   printf("Press S to get State\n");
+   printf("\n");
+   printf("Press X to eXit\n");
+
+   while (1)
+   {
+      memset(&buffer,0,sizeof(buffer));
+      fgets(buffer, sizeof(buffer), stdin);
+      ProcessCommand(buffer[0]);
+      if (buffer[0] == 'X')
+         goto done;
+   }
+
+done:
+   ProcessCommand('R');
+   sleep(1);
+   ProcessCommand('D');
+   ant_deinit();
+
+
+out:
+   return ret;
+}
+
diff --git a/app/ant_app.h b/app/ant_app.h
new file mode 100644
index 0000000..1806975
--- /dev/null
+++ b/app/ant_app.h
@@ -0,0 +1,25 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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.
+ */
+
+
+#ifndef __ANT_APP_H
+#define __ANT_APP_H
+
+
+
+#endif
diff --git a/src/bluez_hci/Android.mk b/src/bluez_hci/Android.mk
new file mode 100644
index 0000000..0320a39
--- /dev/null
+++ b/src/bluez_hci/Android.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2009 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.
+#
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"wl12xx")
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -g -c -W -Wall -O2
+
+# Check which chip is used so correct values in messages
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"wl12xx")
+LOCAL_CFLAGS += -DBOARD_ANT_DEVICE_WILINK
+endif # BOARD_ANT_WIRELESS_DEVICE = wl12xx
+
+LOCAL_C_INCLUDES := \
+   $(LOCAL_PATH)/../common/inc \
+   $(LOCAL_PATH)/inc \
+   system/bluetooth/bluez-clean-headers \
+
+ifeq ($(BOARD_ANT_WIRELESS_POWER),"bluedroid")
+LOCAL_CFLAGS += -DBOARD_HAVE_ANT_WIRELESS
+LOCAL_C_INCLUDES += system/bluetooth/bluedroid/include/bluedroid
+endif # BOARD_ANT_WIRELESS_POWER = bluedroid
+
+LOCAL_C_INCLUDE += $(JNI_H_INCLUDE)
+
+LOCAL_SRC_FILES := \
+   ../../JAntNative.cpp \
+   ../common/ant_utils.c \
+   ant_native_hci.c \
+   ant_rx.c \
+   ant_tx.c \
+
+# jni
+LOCAL_SHARED_LIBRARIES +=  \
+   libnativehelper \
+
+# chip power
+LOCAL_SHARED_LIBRARIES += \
+   libbluedroid \
+
+# logging
+LOCAL_SHARED_LIBRARIES += \
+   libcutils \
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libantradio
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # BOARD_ANT_WIRELESS_DEVICE = "wl12xx"
+
diff --git a/src/bluez_hci/ant_native_hci.c b/src/bluez_hci/ant_native_hci.c
new file mode 100644
index 0000000..4650f62
--- /dev/null
+++ b/src/bluez_hci/ant_native_hci.c
@@ -0,0 +1,823 @@
+/*
+* ANT Stack
+*
+* Copyright 2009 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_hci.c
+*
+*   BRIEF:
+*        This file provides the HCI implementation of ant_native.h
+*
+*
+\******************************************************************************/
+
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "antradio_power.h"
+
+#include "ant_types.h"
+#include "ant_native.h"
+#include "ant_utils.h"
+#include "ant_version.h"
+
+#include "ant_rx.h"
+#include "ant_tx.h"
+#include "ant_hciutils.h"
+#include "ant_log.h"
+
+static pthread_mutex_t         txLock;
+pthread_mutex_t                enableLock;
+
+static ANTRadioEnabledStatus radio_status = RADIO_STATUS_DISABLED;
+ANTRadioEnabledStatus get_and_set_radio_status(void);
+
+////////////////////////////////////////////////////////////////////
+//  ant_init
+//
+//  Initialises the native environment.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_FAILED if could not initialize mutex
+//
+//  Psuedocode:
+/*
+LOCK antdevice_LOCK
+    CREATE mutex for locking Tx attempt
+    IF could not create mutex
+        RESULT = ANT_STATUS_FAILED
+    ELSE
+        CREATE mutex for locking enable/disable
+        IF could not create mutex
+            RESULT = ANT_STATUS_FAILED
+        ELSE
+            RESULT = ANT_STATUS_SUCCESS
+        ENDIF
+    ENDIF
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_init(void)
+{
+   int mutexResult;
+   ANTStatus status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   mutexResult = pthread_mutex_init(&txLock, NULL); //use default attr
+   if (mutexResult)
+   {
+      ANT_ERROR("Tx Lock mutex initialization failed: %s", strerror(mutexResult));
+   }
+   else
+   {
+      mutexResult = pthread_mutex_init(&enableLock, NULL);
+      if (mutexResult)
+      {
+         ANT_ERROR("Enable Lock mutex init failed %s", strerror(mutexResult));
+      }
+      else
+      {
+         status = ANT_STATUS_SUCCESS;
+      }
+   }
+
+   ANT_FUNC_END();
+   return status;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//  ant_deinit
+//
+//  De-initialises the native environment.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_FAILED if could not de-initialize mutex
+//
+//  Psuedocode:
+/*
+LOCK antdevice_LOCK (also Init and Tx)
+    DESTROY mutex for locking Tx attempt
+    IF could not destroy mutex
+        RESULT = ANT_STATUS_FAILED
+    ELSE
+        DESTROY mutex for locking enable/disable
+        IF coult not destroy mutex
+            RESULT = ANT_STATUS_FAILED
+        ELSE
+            RESULT = ANT_STATUS_SUCCESS
+        ENDIF
+    ENDIF
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_deinit(void)
+{
+   int mutexResult;
+   ANTStatus result_status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   mutexResult = pthread_mutex_destroy(&txLock);
+   if (mutexResult)
+   {
+      ANT_ERROR("Tx Lock mutex destroy failed: %s", strerror(mutexResult));
+   }
+   else
+   {
+      mutexResult = pthread_mutex_destroy(&enableLock);
+      if (mutexResult)
+      {
+         ANT_ERROR("Enable Lock mutex destroy failed: %s", strerror(mutexResult));
+      }
+      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
+//      On Android this is in the Bluedroid module.
+//      On Linux this is device specific
+//
+//  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
+    LOCK tx_LOCK
+        IF state is not enabled
+            STATE = ENABLING
+        ENDIF
+        ant enable
+        IF ant_enable success
+            IF rx thread is running
+                STATE = ENABLED
+                RESULT = SUCCESS
+            ELSE
+                start rx thread
+                IF starting rx thread fails
+                    ant disable
+                    get state
+                    IF state is enabled
+                        log a serious error
+                    ENDIF
+                    RESULT = FAILED
+                ELSE
+                    STATE = ENABLED
+                    RESULT = SUCCESS
+                ENDIF
+            ENDIF
+        ELSE
+            get state
+            IF state is enabled
+                log a serious error
+            ENDIF
+            RESULT = FAILURE
+        ENDIF
+    UNLOCK
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_enable_radio(void)
+{
+   int result;
+   int lockResult;
+   ANTStatus result_status = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting enableLock in %s", __FUNCTION__);
+   lockResult = pthread_mutex_lock(&enableLock);
+   if(lockResult)
+   {
+      ANT_ERROR("Enable failed to get enableLock mutex: %s", strerror(lockResult));
+      return ANT_STATUS_FAILED;
+   }
+   ANT_DEBUG_V("got enableLock in %s", __FUNCTION__);
+
+   ANT_DEBUG_V("getting txLock in %s", __FUNCTION__);
+   lockResult = pthread_mutex_lock(&txLock);
+   if (lockResult)
+   {
+      ANT_ERROR("Enable txLock failed: %s", strerror(lockResult));
+      pthread_mutex_unlock(&enableLock);
+      return ANT_STATUS_FAILED;
+   }
+   ANT_DEBUG_V("got txLock in %s", __FUNCTION__);
+
+   if (get_and_set_radio_status() != RADIO_STATUS_ENABLED)
+   {
+      if (RxParams.thread)
+      {
+         ANT_WARN("in enable call: rx thread still exists but radio crashed. trying to recover");
+         ANT_DEBUG_V("radio crashed, letting rx thread join");
+         pthread_join(RxParams.thread, NULL);
+         RxParams.thread = 0;
+         ANT_DEBUG_V("recovered. joined by rx thread");
+      }
+      ANT_DEBUG_I("radio_status (%d -> %d)", radio_status, RADIO_STATUS_ENABLING);
+      radio_status = RADIO_STATUS_ENABLING;
+
+      if (RxParams.pfStateCallback)
+         RxParams.pfStateCallback(radio_status);
+   }
+
+   result = ant_enable();
+   ANT_DEBUG_D("ant_enable() result is %d", result);
+   if (result == 0)
+   {
+      if (RxParams.thread)
+      {
+         result_status = ANT_STATUS_SUCCESS;
+         radio_status = RADIO_STATUS_ENABLED; // sanity assign, cant be enabling
+         ANT_DEBUG_D("ANT radio re-enabled");
+      }
+      else
+      {
+         result = pthread_create(&RxParams.thread, NULL, ANTHCIRxThread, NULL);
+         if (result)
+         {
+            ANT_ERROR("Thread initialization failed: %s", strerror(result));
+            result_status = ANT_STATUS_FAILED;
+         }
+         else
+         {
+            result_status = ANT_STATUS_SUCCESS;
+            if (radio_status == RADIO_STATUS_ENABLING)
+            {
+               ANT_DEBUG_I("radio_status (%d -> %d)", radio_status, RADIO_STATUS_ENABLED);
+               radio_status = RADIO_STATUS_ENABLED;
+
+               if (RxParams.pfStateCallback)
+                  RxParams.pfStateCallback(radio_status);
+            }
+            else
+            {
+               ANT_WARN("radio was already enabled but rx thread was not running");
+            }
+         }
+      }
+   }
+   else
+   {
+      result_status = ANT_STATUS_TRANSPORT_INIT_ERR;
+   }
+
+   if (result_status != ANT_STATUS_SUCCESS)
+   {
+      ant_disable();
+
+      switch (get_and_set_radio_status())
+      {
+         case RADIO_STATUS_ENABLED:
+            ANT_ERROR("SERIOUS: enable failed, but ANT is enabled without a rx thread");
+            break;
+         default:
+            ANT_DEBUG_D("Enable failed, after cleanup chip is not enabled");
+            break;
+      }
+   }
+
+   ANT_DEBUG_V("releasing txLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&txLock);
+   ANT_DEBUG_V("released txLock in %s", __FUNCTION__);
+
+   ANT_DEBUG_V("releasing enableLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&enableLock);
+   ANT_DEBUG_V("released enableLock in %s", __FUNCTION__);
+
+   ANT_FUNC_END();
+   return result_status;
+}
+
+ANTStatus ant_radio_hard_reset(void)
+{
+   ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
+   ANT_FUNC_START();
+   ANT_FUNC_END();
+   return result_status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_disable_radio
+//
+//  Disables the HCI transport and powers off the ANT part.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      Success:
+//          ANT_STATUS_SUCCESS
+//      Failures:
+//          ANT_STATUS_FAILED if could not get mutex
+//          ANT_STATUS_NOT_DE_INITIALIZED if ant_disable failed
+//
+//  Psuedocode:
+/*
+LOCK enable_LOCK
+    LOCK tx_LOCK
+        IF not disabled
+            STATE = DISABLING
+        ENDIF
+        ant disable
+        IF rx thread is running
+            wait for rx thread to terminate
+        ENDIF
+        get radio status
+        IF radio is disabled
+            RESULT = SUCCESS
+        ELSE IF radio is enabled
+            log a serious error
+            RESULT = FAILURE
+        ELSE
+            RESULT = FAILURE
+        ENDIF
+    UNLOCK
+UNLOCK
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_disable_radio(void)
+{
+   int result;
+   int lockResult;
+   ANTStatus ret = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting enableLock in %s", __FUNCTION__);
+   lockResult = pthread_mutex_lock(&enableLock);
+   if(lockResult)
+   {
+      ANT_ERROR("Disable failed to get enableLock mutex: %s", strerror(lockResult));
+      return ANT_STATUS_FAILED;
+   }
+   ANT_DEBUG_V("got enableLock in %s", __FUNCTION__);
+
+   ANT_DEBUG_V("getting txLock in %s", __FUNCTION__);
+   lockResult = pthread_mutex_lock(&txLock);
+   if (lockResult)
+   {
+      ANT_ERROR("Disable txLock failed: %s", strerror(lockResult));
+      pthread_mutex_unlock(&enableLock);
+      return ANT_STATUS_FAILED;
+   }
+   ANT_DEBUG_V("got txLock in %s", __FUNCTION__);
+
+   if (get_and_set_radio_status() != RADIO_STATUS_DISABLED)
+   {
+      ANT_DEBUG_I("radio_status (%d -> %d)", radio_status, RADIO_STATUS_DISABLING);
+      radio_status = RADIO_STATUS_DISABLING;
+
+      if (RxParams.pfStateCallback)
+         RxParams.pfStateCallback(radio_status);
+   }
+
+   result = ant_disable();
+   ANT_DEBUG_D("ant_disable() result is %d", result);
+
+   // If rx thread exists ( != 0)
+   if (RxParams.thread)
+   {
+      ANT_DEBUG_V("quit rx thread, joining");
+      pthread_join(RxParams.thread, NULL);
+      RxParams.thread = 0;
+      ANT_DEBUG_V("joined by rx thread");
+   }
+   else
+   {
+      ANT_DEBUG_W("rx thread is 0 (not created?)");
+   }
+
+   switch (get_and_set_radio_status())
+   {
+      case RADIO_STATUS_DISABLED:
+         ret = ANT_STATUS_SUCCESS;
+         break;
+      case RADIO_STATUS_ENABLED:
+         ANT_ERROR("SERIOUS: ANT was disabled, rx thread quit, but ANT is enabled");
+         ret = ANT_STATUS_FAILED;
+         break;
+      default:
+         ret = ANT_STATUS_NOT_DE_INITIALIZED;
+         break;
+   }
+
+   ANT_DEBUG_V("releasing txLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&txLock);
+   ANT_DEBUG_V("released txLock in %s", __FUNCTION__);
+
+   ANT_DEBUG_V("releasing enableLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&enableLock);
+   ANT_DEBUG_V("released enableLock in %s", __FUNCTION__);
+
+   ANT_FUNC_END();
+   return ret;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//  ant_radio_enabled_status
+//
+//  Returns if the chip/transport is disabled/disabling/enabling/enabled. This
+//  function will NOT overwrite internal state variable enabling or disabling.
+//  It will call get_and_set_radio_status() if not enabling/disabling which can
+//  change internal state on errors.
+//
+//  Parameters:
+//      -
+//
+//  Returns:
+//      The current radio status (ANTRadioEnabledStatus)
+//
+//  Psuedocode:
+/*
+IF Enabling
+    RESULT = Enabling
+ELSE IF Disabling
+    RESULT = Disabling
+ELSE
+    IF ant_is_enabled
+        Enabled
+        RESULT = Enabled
+    ELSE
+        Disabled
+        RESULT = Disabled
+    ENDIF
+ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTRadioEnabledStatus ant_radio_enabled_status(void)
+{
+   ANT_FUNC_START();
+
+   if ((RADIO_STATUS_ENABLING != radio_status) &&
+         (RADIO_STATUS_DISABLING != radio_status))
+   {
+      get_and_set_radio_status();
+   }
+
+   ANT_FUNC_END();
+   return radio_status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  get_and_set_radio_status
+//
+//  Returns if the chip/transport is disabled/enabled/unknown This function WILL
+//  overwrite what it thinks the state is with what the BlueZ core (kernel)
+//  thinks it is. It will overwrite enabling or disabling states, and might
+//  change internal state from enabled, disabled, or unknown to any of these
+//  three on errors.
+//
+//  Paramerters:
+//      -
+//
+//  Returns:
+//      The current radio status (ANTRadioEnabledStatus)
+//
+////////////////////////////////////////////////////////////////////
+ANTRadioEnabledStatus get_and_set_radio_status(void)
+{
+   ANTRadioEnabledStatus orig_status = radio_status;
+   ANT_FUNC_START();
+
+   switch (ant_is_enabled())
+   {
+      case 0:
+         radio_status = RADIO_STATUS_DISABLED;
+         break;
+      case 1:
+         radio_status = RADIO_STATUS_ENABLED;
+         break;
+      default:
+         ANT_ERROR("getting chip state returned an error");
+         radio_status = RADIO_STATUS_UNKNOWN;
+         break;
+   }
+   if (orig_status != radio_status)
+   {
+      ANT_DEBUG_I("radio_status (%d -> %d)", orig_status, radio_status);
+
+      if (RxParams.pfStateCallback)
+         RxParams.pfStateCallback(radio_status);
+   }
+
+   ANT_FUNC_END();
+   return radio_status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  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 recieved messages.
+//
+//  Returns:
+//          ANT_STATUS_SUCCESS
+//
+//  Psuedocode:
+/*
+    Rx Callback = rx_callback_func
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
+{
+   ANTStatus status = ANT_STATUS_SUCCESS;
+
+   ANT_FUNC_START();
+
+   RxParams.pfRxCallback = rx_callback_func;
+
+   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 recieved 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();
+
+   RxParams.pfStateCallback = state_callback_func;
+
+   ANT_FUNC_END();
+
+   return status;
+}
+
+////////////////////////////////////////////////////////////////////
+//  ant_tx_message
+//
+//  Sends an 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 = NOT ENABLED
+ELSE
+    Lock
+    IF Lock failed
+        RESULT = FAILED
+    ELSE
+        STORE length (little endian) in send buffer
+        STORE data in send buffer
+    ENDIF
+ENDIF
+*/
+////////////////////////////////////////////////////////////////////
+ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg)
+{
+   ANTStatus   status;
+
+   /* Socket for sending HCI commands */
+   int tx_socket = -1;
+
+   int lockResult;
+
+   ANT_FUNC_START();
+
+   ANT_DEBUG_V("getting txLock in %s", __FUNCTION__);
+   lockResult = pthread_mutex_lock(&txLock);
+   if (lockResult)
+   {
+      ANT_ERROR("ant_tx_message, could not get txLock: %s", strerror(lockResult));
+      return ANT_STATUS_FAILED;
+   }
+
+   ANT_DEBUG_V("got txLock in %s", __FUNCTION__);
+
+   if(RADIO_STATUS_ENABLED != get_and_set_radio_status())
+   {
+      ANT_DEBUG_E("ant_tx_message, ANT not enabled - ABORTING. Radio status = %d",
+                                                                  radio_status);
+      ANT_DEBUG_V("releasing txLock in %s", __FUNCTION__);
+      pthread_mutex_unlock(&txLock);
+      ANT_DEBUG_V("released txLock in %s", __FUNCTION__);
+      return ANT_STATUS_FAILED_BT_NOT_INITIALIZED;
+   }
+
+   // Open socket
+   tx_socket = ant_open_tx_transport();
+
+   if(tx_socket < 0)
+   {
+      ANT_ERROR("Could not open Tx socket");
+      ANT_DEBUG_V("releasing txLock in %s", __FUNCTION__);
+      pthread_mutex_unlock(&txLock);
+      ANT_DEBUG_V("released txLock in %s", __FUNCTION__);
+      return ANT_STATUS_FAILED;
+   }
+
+   // Send HCI packet
+   ANT_BOOL retryRx;
+   ANT_BOOL retryTx;
+   status = ANT_STATUS_FAILED;
+
+   int MAX_RETRIES_WRITE_FAIL = 10;
+   int MAX_RETRY_TIME_SECS = 10;
+   int commandWriteFailRetries = 0;
+
+   // Start New timed retry code:
+   time_t startTime = time(NULL);
+   time_t endTime = 0;
+   if((time_t)-1 != startTime)
+   {
+      endTime = startTime + MAX_RETRY_TIME_SECS;
+   }
+   else
+   {
+      ANT_ERROR("failed to get current time");
+   }
+
+   do // while (retryTx)
+   {
+      retryTx = ANT_FALSE;
+
+      if(ANT_STATUS_SUCCESS == write_data(pucMesg, ucLen))
+      {
+         do // while (retryRx)
+         {
+            retryRx = ANT_FALSE;
+         
+            if(ANT_TRUE == wait_for_message(tx_socket))
+            {
+               ANT_DEBUG_D("New HCI data available, reading...");
+            
+               status = get_command_complete_result(tx_socket);
+               switch (status)
+               {
+                  case ANT_STATUS_NO_VALUE_AVAILABLE:
+                  {
+                     ANT_WARN("Did not get an expected response for write, trying again");
+                     retryRx = ANT_TRUE;
+                     break;
+                  }
+                  case ANT_STATUS_FAILED:
+                  {
+                     ANT_ERROR("Command Complete: ANT_STATUS_FAILED");
+                     break;
+                  }
+                  case ANT_STATUS_COMMAND_WRITE_FAILED:
+                  {
+                     ANT_ERROR("Command Complete: ANT_STATUS_WRITE_FAILED");
+                   
+                     if(++commandWriteFailRetries < MAX_RETRIES_WRITE_FAIL)
+                     {
+                        ANT_DEBUG_D("Retrying.  Retry count = %d", 
+                                                      commandWriteFailRetries);
+                     
+                        retryTx = ANT_TRUE;
+                     }
+                     else
+                     {
+                        ANT_ERROR("Aborting.  Retry count = %d.  Max retries = %d",
+                              commandWriteFailRetries, MAX_RETRIES_WRITE_FAIL);
+                     }
+                     break;
+                  }
+                  case ANT_STATUS_TRANSPORT_UNSPECIFIED_ERROR:
+                  {
+                     ANT_DEBUG_D("Command Complete: ANT_STATUS_UNSPECIFIED_ERROR");
+                   
+                     time_t currentTime = time(NULL);
+                      
+                     if((time_t)-1 != currentTime)
+                     {
+                        if(currentTime < endTime)
+                        {
+                           ANT_DEBUG_V("Retrying. Current time = %d. "
+                              "End time = %d", (int)currentTime, (int)endTime);
+                        
+                           retryTx = ANT_TRUE;
+                        }
+                        else
+                        {
+                           ANT_ERROR("Command Complete: ANT_STATUS_UNSPECIFIED_ERROR");
+                           ANT_ERROR("Aborting. Current time = %d. End Time = %d",
+                                                (int)currentTime, (int)endTime);
+                        }
+                     }
+                     else
+                     {
+                        ANT_ERROR("Command Complete: failed to get current time");
+                     }
+                  
+                     break;
+                  }
+                  case ANT_STATUS_SUCCESS:
+                  {
+                     break;
+                  }
+                  default:
+                  {
+                     ANT_ERROR("Unhandled command complete status");
+                     break;
+                  }
+               }
+            }
+            else
+            {
+               ANT_WARN("Command Complete: wait for message failed");
+            }
+         } while (retryRx);
+      }
+      else
+      {
+         ANT_ERROR("write failed");
+         retryRx = ANT_FALSE;
+      
+         status = ANT_STATUS_FAILED;
+      }
+   } while(retryTx);
+   
+   ant_close_tx_transport(tx_socket);
+
+   ANT_DEBUG_V("releasing txLock in %s", __FUNCTION__);
+   pthread_mutex_unlock(&txLock);
+   ANT_DEBUG_V("released txLock in %s", __FUNCTION__);
+
+   ANT_FUNC_END();
+
+   return status;
+}
+
+const char *ant_get_lib_version()
+{
+   return "libantradio.so Bluez HCI Transport Version " 
+          LIBANT_STACK_MAJOR "." LIBANT_STACK_MINOR "." LIBANT_STACK_INCRE;
+}
+
diff --git a/src/bluez_hci/ant_rx.c b/src/bluez_hci/ant_rx.c
new file mode 100644
index 0000000..76d29ff
--- /dev/null
+++ b/src/bluez_hci/ant_rx.c
@@ -0,0 +1,275 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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.c
+*
+*   BRIEF:
+*      This file Implements the receive thread for an HCI implementation
+*      using Vendor Specific messages.
+*
+*
+\******************************************************************************/
+
+
+#define _GNU_SOURCE /* needed for PTHREAD_MUTEX_RECURSIVE */
+
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include "antradio_power.h"
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#include "ant_rx.h"
+#include "ant_hciutils.h"
+#include "ant_types.h"
+#include "ant_framing.h"
+#include "ant_log.h"
+#undef LOG_TAG
+#define LOG_TAG "antradio_rx"
+
+static char EVT_PKT_VENDOR_FILTER[] = {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                       0x00,0x00,0x00,0x80,0x00,0x05,0x00,0x00};
+
+/* Global Options */
+ANTHCIRxParams RxParams = {
+   .pfRxCallback = NULL,
+   .pfStateCallback = NULL,
+   .thread = 0
+};
+
+extern pthread_mutex_t enableLock;
+extern ANTRadioEnabledStatus get_and_set_radio_status(void);
+/*
+ * This thread opens a Bluez HCI socket and waits for ANT messages.
+ */
+void *ANTHCIRxThread(void *pvHCIDevice)
+{
+   int ret = ANT_STATUS_SUCCESS;
+   int rxSocket;
+   int len;
+   unsigned char buf[HCI_MAX_EVENT_SIZE];
+   int result;
+   ANT_FUNC_START();
+
+   (void)pvHCIDevice; //unused waring
+
+   ANT_DEBUG_D("Entering ANTHCIRxThread");
+
+   rxSocket = create_hci_sock();
+   if (rxSocket < 0)
+   {
+      ANT_DEBUG_E("can't open HCI socket in rx thread: %s", strerror(errno));
+
+      ret = ANT_STATUS_FAILED;
+      goto out;
+   }
+
+   if (setsockopt(rxSocket, SOL_HCI, HCI_FILTER, &EVT_PKT_VENDOR_FILTER,
+                                             sizeof(EVT_PKT_VENDOR_FILTER)) < 0)
+   {
+      ANT_ERROR("failed to set socket options: %s", strerror(errno));
+
+      ret = ANT_STATUS_FAILED;
+      goto close;
+   }
+
+   /* continue running as long as not terminated */
+   while (get_and_set_radio_status() == RADIO_STATUS_ENABLED)
+   {
+      struct pollfd p;
+      int n;
+
+      p.fd = rxSocket;
+      p.events = POLLIN;
+
+      ANT_DEBUG_V("    RX: Polling HCI for data...");
+
+      /* poll socket, wait for ANT messages */
+      while ((n = poll(&p, 1, 2500)) == -1)
+      {
+         if (errno == EAGAIN || errno == EINTR)
+            continue;
+
+         ANT_ERROR("failed to poll socket: %s", strerror(errno));
+
+         ret = ANT_STATUS_FAILED;
+         goto close;
+      }
+
+      /* we timeout once in a while */
+      /* this let's us the chance to check if we were terminated */
+      if (0 == n)
+      {
+         ANT_DEBUG_V("    RX: Timeout");
+         continue;
+      }
+
+      ANT_DEBUG_D("New HCI data available, reading...");
+
+      /* read newly arrived data */
+      /* TBD: rethink assumption about single arrival */
+      while ((len = read(rxSocket, buf, sizeof(buf))) < 0)
+      {
+         if (errno == EAGAIN || errno == EINTR)
+            continue;
+
+         ANT_ERROR("failed to read socket: %s", strerror(errno));
+
+         ret = ANT_STATUS_FAILED;
+         goto close;
+      }
+
+    // 0 = packet type eg. HCI_EVENT_PKT
+    // FOR EVENT:
+    //   1 = event code  eg. EVT_VENDOR, EVT_CMD_COMPLETE
+    //   2 = Parameter total length
+    //   3... parameters
+    //  FOR CC
+    //      3   = Num HCI Command packets allowed to be sent
+    //      4+5 = ANT Opcode
+    //      6   = Result ??
+    //   FOR VS
+    //     3+4 = ANT Opcode
+    //     5   = length
+    //     6 ? MSB of length ?
+    //     7... ant message
+
+      if (len >= 7)
+      {
+          ANT_DEBUG_V("HCI Data: [%02X][%02X][%02X][%02X][%02X][%02X][%02X]...",
+             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+      }
+      else
+      {
+         ANT_ERROR("Failed to read full header off socket. len = %d", len);
+         continue;
+      }
+
+      if (len != (buf[2] + 3))
+      {
+         ANT_WARN("HCI packet length(%d) and bytes read(%d) dont match", buf[2] + 3, len);
+      }
+
+      if(HCI_EVENT_PKT == buf[0])
+      {
+         ANT_DEBUG_D("Received Event Packet");
+
+         if (EVT_VENDOR == buf[1])
+         {
+            if ((HCI_VSOP_ANT_LSB == buf[3]) && (HCI_VSOP_ANT_MSB == buf[4]))
+            {
+               ANT_DEBUG_D("Received ANT VS Message");
+
+               if (len < 9)
+               {
+                  ANT_ERROR("Malformed ANT header");
+                  ret = ANT_STATUS_FAILED;
+                  goto close;
+               }
+
+               ANT_DEBUG_V("ANT Mesg: ANTMesgSize:%d ANTMesgID:0x%02X ...",
+                                                               buf[7], buf[8]);
+
+               ANT_SERIAL(&(buf[7]), buf[5], 'R');
+
+               if(RxParams.pfRxCallback != NULL)
+               {
+                  RxParams.pfRxCallback(buf[5], &(buf[7]));
+               }
+               else
+               {
+                  ANT_ERROR("Can't send rx message - no callback registered");
+               }
+
+               continue;
+            }
+            else
+            {
+               ANT_DEBUG_W("Vendor Specific message for another vendor. "
+                                                         "Should filter out");
+            }
+         }
+         else
+         {
+            ANT_DEBUG_V("Other Event Packet, Ignoring");
+         }
+      }
+      else
+      {
+         ANT_DEBUG_V("Non-Event Packet, Ignoring");
+      }
+   }
+
+close:
+   result = pthread_mutex_trylock(&enableLock);
+   ANT_DEBUG_D("rx thread close: trylock enableLock returned %d", result);
+
+   if (result == 0)
+   {
+      ANT_DEBUG_W("rx thread socket has unexpectedly crashed");
+      if (RxParams.pfStateCallback)
+         RxParams.pfStateCallback(RADIO_STATUS_DISABLING);
+      ant_disable();
+      get_and_set_radio_status();
+      RxParams.thread = 0;
+      pthread_mutex_unlock(&enableLock);
+   }
+   else if (result == EBUSY)
+   {
+      ANT_DEBUG_V("rx thread socket was closed");
+   }
+   else
+   {
+      ANT_ERROR("rx thread close: trylock failed: %s", strerror(result));
+   }
+
+   if (-1 == close(rxSocket))
+   {
+      ANT_ERROR("failed to close hci device (socket handle=%#x): %s", rxSocket, strerror(errno));
+   }
+   else
+   {
+      ANT_DEBUG_D("closed hci device (socket handle=%#x)", rxSocket);
+   }
+
+out:
+   ANT_FUNC_END();
+
+   pthread_exit((void *)ret);
+
+#if defined(ANDROID)
+   return 0;
+#endif
+}
+
diff --git a/src/bluez_hci/ant_tx.c b/src/bluez_hci/ant_tx.c
new file mode 100644
index 0000000..2757a3b
--- /dev/null
+++ b/src/bluez_hci/ant_tx.c
@@ -0,0 +1,358 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_tx.c
+*
+*   BRIEF:
+*      This file Implements the transmit functionality for an HCI implementation
+*      using Vendor Specific messages.
+*
+*
+\******************************************************************************/
+
+#include <errno.h>
+#include <poll.h>
+#include <sys/uio.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#include "ant_types.h"
+#include "ant_hciutils.h"
+#include "ant_framing.h"
+#include "ant_utils.h"
+#include "ant_log.h"
+#undef LOG_TAG
+#define LOG_TAG "antradio_tx"
+
+static char EVT_PKT_CMD_COMPLETE_FILTER[] = {0x10,0x00,0x00,0x00,0x00,0x40,0x00,
+                                 0x00,0x00,0x00,0x00,0x00,0xD1,0xFD,0x00,0x00};
+
+int g_ant_cmd_socket = -1;
+
+int ant_open_tx_transport(void)
+{
+   int socket = -1;
+   ANT_FUNC_START();
+
+   socket = create_hci_sock();
+   
+   if (socket < 0) 
+   {
+      ANT_DEBUG_E("failed to open HCI socket for tx: %s", strerror(errno));
+   }
+   else
+   {
+      g_ant_cmd_socket = socket;
+      ANT_DEBUG_D("socket handle %#x", g_ant_cmd_socket);
+      if (setsockopt(g_ant_cmd_socket, SOL_HCI, HCI_FILTER, 
+         &EVT_PKT_CMD_COMPLETE_FILTER, sizeof(EVT_PKT_CMD_COMPLETE_FILTER)) < 0)
+      {
+         ANT_ERROR("failed to set socket options: %s", strerror(errno));
+         close(socket);
+         socket = -1;
+      }
+   }
+
+   ANT_FUNC_END();
+   return socket;
+}
+
+void ant_close_tx_transport(int socket)
+{
+   ANT_FUNC_START();
+
+   if(0 < socket)
+   {
+      if (0 == close(socket)) 
+      {
+         ANT_DEBUG_D("closed hci device (socket handle=%#x)", socket);
+      }
+      else
+      {
+         ANT_ERROR("failed to close hci device (socket handle=%#x): %s", socket, strerror(errno));
+      }
+   }
+   else
+   {
+      ANT_DEBUG_E("requested close on socket %#x. invalid param", socket);
+   }
+
+   ANT_FUNC_END();
+}
+
+/* 
+Format of an HCI WRITE command to ANT chip:
+
+HCI Header:
+----------
+- HCI Packet Type:                                                      1 byte
+
+- HCI Opcode:                                                           2 bytes
+                                                               (LSB, MSB - LE)
+- HCI Parameters Total Len (total length of all subsequent fields):     1 byte
+
+HCI Parameters:
+--------------
+- VS Parameters Len (total length of ANT Mesg inculding Len/ID)         2 bytes
+                                                               (LSB, MSB - LE)
+- ANT Mesg Len (N = number of bytes in ANT Mesg Data):                  1 byte
+- ANT Mesg ID:                                                          1 byte
+- ANT Mesg Data:                                                        N bytes 
+*/
+
+ANT_BOOL wait_for_message(int socket)
+{
+   struct pollfd p;
+   int n;
+
+   ANT_BOOL bReturn = ANT_FALSE;
+   ANT_BOOL bRetry = ANT_FALSE;
+
+   ANT_FUNC_START();
+
+   p.fd = socket;
+   p.events = POLLIN;
+
+   do
+   {
+      bRetry = ANT_FALSE;
+   
+      ANT_DEBUG_V("    CC: Polling HCI for data...");
+   
+      /* poll socket, wait for ANT messages */
+      n = poll(&p, 1, 2500);
+      if (0 > n)
+      {
+         if (errno == EAGAIN || errno == EINTR)
+         {
+            ANT_DEBUG_W("    CC: error: %s", strerror(errno));
+            bRetry = ANT_TRUE;
+         }
+         else
+         {
+            ANT_ERROR("failed to poll socket. error: %s", strerror(errno));
+         }
+      }
+
+      /* timeout */
+      else if (0 == n)
+      {
+         ANT_ERROR("SERIOUS: Timeouted getting Command Complete");
+      }
+      else if(0 < n)
+      {
+         // There is data to read.
+         bReturn = ANT_TRUE;
+      }
+
+   } while(ANT_TRUE == bRetry);
+
+   ANT_FUNC_END();
+   
+   return bReturn;
+}
+
+ANTStatus write_data(ANT_U8 ant_message[], int ant_message_len)
+{
+   ANTStatus ret = ANT_STATUS_FAILED;
+   ANT_BOOL retry = ANT_FALSE;
+   int bytes_written;
+   struct iovec iov[2];
+   hci_vendor_cmd_packet_t hci_header;
+   ANT_U16 hci_opcode;
+
+   ANT_FUNC_START();
+
+   hci_opcode = cmd_opcode_pack(OGF_VENDOR_CMD, HCI_CMD_ANT_MESSAGE_WRITE);
+
+   hci_header.packet_type = HCI_COMMAND_PKT;
+   ANT_UTILS_StoreLE16(hci_header.cmd_header.opcode, hci_opcode);
+   hci_header.cmd_header.plen = ((ant_message_len + HCI_VENDOR_HEADER_SIZE) & 0xFF);
+   ANT_UTILS_StoreLE16(hci_header.vendor_header.hcilen, ant_message_len);
+
+   iov[0].iov_base = &hci_header;
+   iov[0].iov_len = sizeof(hci_header);
+   iov[1].iov_base = ant_message;
+   iov[1].iov_len = ant_message_len;
+
+   do //while retry
+   {
+      retry = ANT_FALSE;
+
+      if (g_ant_cmd_socket < 0)
+      {
+         ANT_DEBUG_E("bad socket handle %#x", g_ant_cmd_socket);
+         return ANT_STATUS_INTERNAL_ERROR;
+      }
+
+      ANT_SERIAL(ant_message, ant_message_len, 'T');
+
+      bytes_written = writev(g_ant_cmd_socket, iov, 2);
+
+      ANT_DEBUG_D("writing to socket %#x returned %d", g_ant_cmd_socket, 
+                                                               bytes_written);
+
+//      bytes_written < 0                   = error (check errno)
+//      bytes_written = 0                   = No data written
+//      bytes_written < sizeof(hci_message) = not all data written
+//      bytes_written = sizeof(hci_message) = all data written
+
+      if(bytes_written < 0)
+      {
+         ANT_ERROR("write to HCI failed: %s", strerror(errno));
+
+         if (errno == EAGAIN || errno == EINTR)
+         {
+            ANT_DEBUG_D("Retrying write to HCI");
+            retry = ANT_TRUE;
+         }
+         else
+         {
+            ret = ANT_STATUS_FAILED;
+         }
+      }
+      else if(bytes_written < ((int)sizeof(hci_header) + ant_message_len))
+      {
+         ANT_DEBUG_D("Only %d bytes written to HCI.", bytes_written);
+         ret = ANT_STATUS_FAILED;
+      }
+      else
+      {
+         ANT_DEBUG_V("writev successful");
+         ret = ANT_STATUS_SUCCESS;
+      }
+   } while(retry);
+
+   ANT_FUNC_END();
+ 
+   return ret;
+}
+
+// Returns:
+//  ANT_STATUS_NO_VALUE_AVAILABLE          if not a CC packet
+//  ANT_STATUS_FAILED                      if could not read socket or not a 
+//                                                       valid length CC packet
+//  ANT_STATUS_TRANSPORT_UNSPECIFIED_ERROR if CC indicates an unspecified error
+//  ANT_STATUS_COMMAND_WRITE_FAILED        if CC indicates a failure
+//  ANT_STATUS_SUCCESS                     if CC indicates message was received 
+ANTStatus get_command_complete_result(int socket)
+{
+   ANTStatus status = ANT_STATUS_NO_VALUE_AVAILABLE;
+   int len;
+   ANTStatus ret = ANT_STATUS_SUCCESS;
+   ANT_U8 ucResult = -1;
+   ANT_U8 buf[ANT_NATIVE_MAX_PARMS_LEN];
+
+   ANT_FUNC_START();
+   ANT_DEBUG_V("reading off socket %#x", socket);
+
+   /* read newly arrived data */
+   while ((len = read(socket, buf, sizeof(buf))) < 0)
+   {
+      if (errno == EAGAIN || errno == EINTR)
+         continue;
+
+      ANT_ERROR("failed to read socket. error: %s", strerror(errno));
+
+      ret = ANT_STATUS_FAILED;
+      goto close;
+   }
+
+   ANT_SERIAL(buf, len, 'C');
+
+   ANT_DEBUG_V("HCI Data: [%02X][%02X][%02X][%02X][%02X][%02X][%02X]...", 
+              buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
+
+   // 0 = packet type eg. HCI_EVENT_PKT
+   // FOR EVENT:
+   //   1 = event code  eg. EVT_VENDOR, EVT_CMD_COMPLETE
+   //   2 = Parameter total length
+   //   3... parameters
+   //  FOR CC
+   //      3   = Num HCI Vommand packets (allowed to be sent)
+   //      4+5 = ANT Opcode
+   //      6   = Result ??
+   //   FOR VS
+   //     3+4 = ANT Opcode
+   //     5   = length
+   //     6 ? MSB of length ?
+   //     7... ant message
+
+   if(HCI_EVENT_PKT == buf[0])
+   {
+      ANT_DEBUG_D("Received Event Packet");
+
+      if(EVT_CMD_COMPLETE == buf[1])
+      {
+         if(len < HCI_EVENT_OVERHEAD_SIZE) 
+         {
+            status = ANT_STATUS_FAILED;
+         }
+         else
+         {
+            if((HCI_CMD_OPCODE_ANT_LSB == buf[4]) && 
+                                         (HCI_CMD_OPCODE_ANT_MSB == buf[5]))
+            {
+               ucResult = buf[6];
+
+               ANT_DEBUG_V("Received COMMAND COMPLETE");
+            }
+            else
+            {
+               ANT_DEBUG_V("Command complete has wrong opcode");
+            }
+         }
+
+         /*
+          * if got a status byte, pass it forward, otherwise pass a failure
+          * status
+          */
+         if(status != ANT_STATUS_FAILED)
+         {
+            if(ucResult == 0)
+            {
+               ANT_DEBUG_D("Command Complete = SUCCESS");
+               status = ANT_STATUS_SUCCESS;
+            }
+            else if(ucResult == HCI_UNSPECIFIED_ERROR)
+            {
+               ANT_DEBUG_D("Command Complete = UNSPECIFIED_ERROR");
+
+               status = ANT_STATUS_TRANSPORT_UNSPECIFIED_ERROR;
+            }
+            else
+            {
+               status = ANT_STATUS_COMMAND_WRITE_FAILED;
+               ANT_DEBUG_D("Command Complete = WRITE_FAILED");
+            }
+         }
+      }
+      else
+      {
+         ANT_DEBUG_W("Other Event Packet, Should filter out");
+      }
+   }
+
+close:
+   ANT_FUNC_END();
+   return status;
+}
+
diff --git a/src/bluez_hci/inc/ant_framing.h b/src/bluez_hci/inc/ant_framing.h
new file mode 100644
index 0000000..7d01844
--- /dev/null
+++ b/src/bluez_hci/inc/ant_framing.h
@@ -0,0 +1,50 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_Framing.h
+*
+*   BRIEF:          
+*		This file defines ANT specific HCI values used by the ANT chip.
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_HCIFRAMING_H
+#define __ANT_HCIFRAMING_H
+
+#ifdef BOARD_ANT_DEVICE_WILINK
+
+/* Number to used by the VS Parameters Len field */
+#define ANT_NATIVE_HCI_VS_PARMS_LEN_FIELD_LEN    (2)
+
+#define HCI_CMD_ANT_MESSAGE_WRITE                ((ANT_U16)0x01D1)
+
+#define HCI_CMD_OPCODE_ANT_LSB                   0xD1
+#define HCI_CMD_OPCODE_ANT_MSB                   0xFD
+
+#define HCI_VSOP_ANT_LSB                         0x00
+#define HCI_VSOP_ANT_MSB                         0x05
+
+#else
+
+#error "Board ANT Device Type not recognised"
+
+#endif
+
+#endif /* __ANT_HCIFRAMING_H */
diff --git a/src/bluez_hci/inc/ant_hciutils.h b/src/bluez_hci/inc/ant_hciutils.h
new file mode 100644
index 0000000..f8cf579
--- /dev/null
+++ b/src/bluez_hci/inc/ant_hciutils.h
@@ -0,0 +1,121 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_hciuntils.h
+*
+*   BRIEF:
+*		This file defines the utility functions for an HCI implementation
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_HCIUTILS_H
+#define __ANT_HCIUTILS_H
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+
+#include "ant_types.h"
+#include "ant_native.h"
+#include "ant_log.h"
+// -------------------------------------------------
+
+#define HCI_COMMAND_HEADER_SIZE 3
+typedef struct {
+   ANT_U8                     opcode[2];           // 0xFDD1 for ANT
+   ANT_U8                     plen;
+} __attribute__ ((packed)) hci_command_header_t;
+
+#define HCI_VENDOR_HEADER_SIZE 2
+typedef struct {
+   ANT_U8                  hcilen[2];
+} __attribute__ ((packed)) hci_vendor_header_t;
+
+#define HCI_COMMAND_OVERHEAD_SIZE ( HCI_COMMAND_HEADER_SIZE + \
+                                    HCI_VENDOR_HEADER_SIZE + 1)
+typedef struct {
+   ANT_U8                     packet_type;         // 0x01 for HCI_COMMAND_PKT
+   hci_command_header_t       cmd_header;
+   hci_vendor_header_t        vendor_header;
+} __attribute__ ((packed)) hci_vendor_cmd_packet_t;
+
+#define HCI_EVENT_HEADER_SIZE 2
+typedef struct {
+   ANT_U8                     event_c;             // 0xFF for Vendor Specific,
+                                                   // 0x0E for EVNT_CMD_COMPLETE
+   ANT_U8                     plen;                // data/parameter length
+} __attribute__ ((packed)) hci_event_header_t;
+
+#define HCI_EVENT_OVERHEAD_SIZE (HCI_EVENT_HEADER_SIZE + 5)
+typedef struct {
+   ANT_U8                     packet_type;         // HCI_EVENT_PKT
+   hci_event_header_t         header;
+   union {
+      struct {
+         ANT_U8               vendor_c[2];         // 0x0500 for ANT
+         ANT_U8               hcilen[2];
+      } vendor;
+      struct {
+         ANT_U8               num_token;
+         ANT_U8               opcode[2];           // 0xFDD1 for ANT
+         ANT_U8               resp;
+      } cmd_cmplt;
+   };
+   ANT_U8                     data[ANT_NATIVE_MAX_PARMS_LEN];  // Should be 255
+} __attribute__ ((packed)) hci_event_packet_t;
+
+typedef struct {
+   union {
+      hci_event_packet_t      hci_event_packet;
+      ANT_U8                  raw_packet[sizeof(hci_event_packet_t)];
+   };
+} rx_data_t;  // Use this is for vendor specific and command complete events
+
+
+// -------------------------------------------------
+
+static inline int create_hci_sock() {
+   struct sockaddr_hci sa;
+   int sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+   if (sk < 0)
+   {
+      ANT_ERROR("Failed to create bluetooth hci socket: %s", strerror(errno));
+   }
+   else
+   {
+      memset(&sa, 0, sizeof(sa));
+      // sockaddr_hci changed from kernel 2.6.37 to 2.6.38 adding member hci_channel
+      // In order to be backwards compatible set it to 0 if it exists (HCI_CHANNEL_RAW)
+      sa.hci_family = AF_BLUETOOTH;
+      sa.hci_dev = 0;
+      if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0)
+      {
+         ANT_ERROR("Failed to bind socket %#x to hci0: %s", sk, strerror(errno));
+         close(sk);
+         sk = -1;
+      }
+   }
+   return sk;
+}
+
+#endif /* __ANT_HCIUTILS_H */
+
+
diff --git a/src/bluez_hci/inc/ant_rx.h b/src/bluez_hci/inc/ant_rx.h
new file mode 100644
index 0000000..c914bb6
--- /dev/null
+++ b/src/bluez_hci/inc/ant_rx.h
@@ -0,0 +1,54 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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.h
+*
+*   BRIEF:
+*		This file defines the receive thread function
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_OS_H
+#define __ANT_OS_H
+
+#include <pthread.h>
+#include "ant_types.h"
+#include "ant_native.h"
+
+typedef struct
+{
+   //The function to call back with received data
+   ANTNativeANTEventCb pfRxCallback;
+
+   //The function to call back with state changes
+   ANTNativeANTStateCb pfStateCallback;
+
+   //The thread object itself
+   pthread_t thread;
+
+} ANTHCIRxParams;
+
+extern ANTHCIRxParams RxParams;
+
+//The message receive thread
+void* ANTHCIRxThread(void* pvHCIDevice);
+
+#endif  /* __ANT_OS_H */
+
diff --git a/src/bluez_hci/inc/ant_tx.h b/src/bluez_hci/inc/ant_tx.h
new file mode 100644
index 0000000..5057011
--- /dev/null
+++ b/src/bluez_hci/inc/ant_tx.h
@@ -0,0 +1,42 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_tx.h
+*
+*   BRIEF:
+*		This file defines the transmit function
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_TX_H
+#define __ANT_TX_H
+
+#include "ant_types.h"
+#include "ant_hciutils.h"
+
+int         ant_open_tx_transport(void);
+void        ant_close_tx_transport(int socket);
+ANT_BOOL    wait_for_message(int socket);
+ANTStatus   write_data(ANT_U8 ant_message[], int ant_message_len);
+
+ANTStatus get_command_complete_result(int socket);
+
+#endif /* __ANT_TX_H */
+
diff --git a/src/chip-B/Android.mk b/src/chip-B/Android.mk
new file mode 100644
index 0000000..5b030ff
--- /dev/null
+++ b/src/chip-B/Android.mk
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"chip-B")
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -g -c -W -Wall -O2
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/../common/inc \
+    $(LOCAL_PATH)/inc \
+
+LOCAL_SRC_FILES:= \
+    ../../JAntNative.cpp \
+    ../common/ant_utils.c \
+    ant_native_chardev.c \
+    ant_rx_chardev.c \
+
+#JNI
+LOCAL_C_INCLUDE += $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES += \
+    libnativehelper
+
+# logging
+LOCAL_SHARED_LIBRARIES += \
+    libcutils
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libantradio
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # BOARD_ANT_WIRELESS_DEVICE = "chip-B"
diff --git a/src/chip-B/ant_native_chardev.c b/src/chip-B/ant_native_chardev.c
new file mode 100644
index 0000000..39e61d7
--- /dev/null
+++ b/src/chip-B/ant_native_chardev.c
@@ -0,0 +1,424 @@
+/*
+ * 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 character device implementation of ant_native.h
+*
+*
+\*******************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h> /* for open() */
+#include <linux/ioctl.h>
+#include <pthread.h>
+
+#include "ant_native.h"
+#include "ant_types.h"
+#include "ant_log.h"
+#include "ant_version.h"
+
+#include "ant_native_chardev.h"
+#include "ant_rx_chardev.h"
+
+#define CHIP_B_CHAR_DEV_IOCTL_RESET          _IO('H', 160)
+
+#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)
+
+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 void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName)
+{
+   pstChnlInfo->pcDevicePath = pcCharDevName;
+   pstChnlInfo->iFd = -1;
+   pstChnlInfo->fnRxCallback = NULL;
+   pstChnlInfo->ucFlowControlResp = FLOW_GO;
+   pstChnlInfo->pstFlowControlCond = &stFlowControlCond;
+   pstChnlInfo->pstFlowControlLock = &stFlowControlLock;
+}
+
+ANTStatus ant_init(void)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+   stRxThreadInfo.stRxThread = 0;
+   stRxThreadInfo.ucRunThread = 0;
+   stRxThreadInfo.ucChipResetting = 0;
+   stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
+   g_fnStateCallback = 0;
+   ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
+   ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
+   uiRet = ANT_STATUS_SUCCESS;
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus ant_deinit(void)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+   uiRet = ANT_STATUS_SUCCESS;
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
+{
+   ANT_FUNC_START();
+   stRxThreadInfo.astChannels[COMMAND_CHANNEL].fnRxCallback = rx_callback_func;
+   stRxThreadInfo.astChannels[DATA_CHANNEL].fnRxCallback = rx_callback_func;
+   ANT_FUNC_END();
+   return ANT_STATUS_SUCCESS;
+}
+
+ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func)
+{
+   ANT_FUNC_START();
+   g_fnStateCallback = state_callback_func;
+   ANT_FUNC_END();
+   return ANT_STATUS_SUCCESS;
+}
+
+ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   int iMutexResult;
+   int iResult;
+   struct timespec stTimeout;
+   int iCondWaitResult;
+   ANT_U8 txBuffer[ANT_HCI_MAX_MSG_SIZE];
+   ANT_FUNC_START();
+   if (ant_radio_enabled_status() != RADIO_STATUS_ENABLED) {
+      uiRet = ANT_STATUS_FAILED_BT_NOT_INITIALIZED;
+      goto out;
+   }
+   txBuffer[CHIP_B_HCI_SIZE_OFFSET] = ucLen;
+   memcpy(txBuffer + CHIP_B_HCI_HEADER_SIZE, pucMesg, ucLen);
+   ANT_SERIAL(txBuffer, ucLen + CHIP_B_HCI_HEADER_SIZE, 'T');
+   switch (txBuffer[CHIP_B_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:
+      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[COMMAND_CHANNEL].ucFlowControlResp = FLOW_STOP;
+      iResult = write(stRxThreadInfo.astChannels[DATA_CHANNEL].iFd, txBuffer, ucLen + CHIP_B_HCI_HEADER_SIZE);
+      if (iResult < 0) {
+         ANT_ERROR("failed to write data message to device: %s", strerror(errno));
+      } else if (iResult != ucLen + CHIP_B_HCI_HEADER_SIZE) {
+         ANT_ERROR("bytes written and message size dont match up");
+      } else {
+         stTimeout.tv_sec = time(0) + CHIP_B_FLOW_GO_WAIT_TIMEOUT_SEC;
+         stTimeout.tv_nsec = 0;
+
+         while (stRxThreadInfo.astChannels[COMMAND_CHANNEL].ucFlowControlResp != 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)
+                  uiRet = ANT_STATUS_HARDWARE_ERR;
+               goto wait_error;
+            }
+         }
+         uiRet = 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__);
+      break;
+   default:
+      iResult = write(stRxThreadInfo.astChannels[COMMAND_CHANNEL].iFd, txBuffer, ucLen + CHIP_B_HCI_HEADER_SIZE);
+      if (iResult < 0) {
+         ANT_ERROR("failed to write message to device: %s", strerror(errno));
+      }  else if (iResult != ucLen + CHIP_B_HCI_HEADER_SIZE) {
+         ANT_ERROR("bytes written and message size dont match up");
+      } else {
+         uiRet = ANT_STATUS_SUCCESS;
+      }
+   }
+out:
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus ant_radio_hard_reset(void)
+{
+   enum ant_channel_type eChannel;
+   int iLockResult;
+   ANTStatus uiRet = 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__);
+
+   stRxThreadInfo.ucChipResetting = 1;
+   if (g_fnStateCallback)
+      g_fnStateCallback(RADIO_STATUS_RESETTING);
+
+   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++)
+      ioctl(stRxThreadInfo.astChannels[eChannel].iFd, CHIP_B_CHAR_DEV_IOCTL_RESET); //TODO only one?
+
+   ant_do_disable();
+
+   if (ant_do_enable()) { /* failed */
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_DISABLED);
+   } else { /* success */
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_RESET);
+      uiRet = 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:
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+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) {
+      if (close(pstChnlInfo->iFd) < 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) {
+      pstChnlInfo->iFd = open(pstChnlInfo->pcDevicePath, O_RDWR);
+      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;
+}
+
+int ant_do_enable(void)
+{
+   int iRet = -1;
+   enum ant_channel_type eChannel;
+   ANT_FUNC_START();
+
+   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;
+}
+
+void ant_do_disable(void)
+{
+   enum ant_channel_type eChannel;
+   ANT_FUNC_START();
+   stRxThreadInfo.ucRunThread = 0;
+   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++)
+      ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]);
+   if (stRxThreadInfo.stRxThread != 0) {
+      if (pthread_join(stRxThreadInfo.stRxThread, NULL) < 0) {
+         ANT_ERROR("failed to join rx thread: %s", strerror(errno));
+      }
+      stRxThreadInfo.stRxThread = 0;
+   } else {
+      ANT_DEBUG_D("rx thread is not running");
+   }
+   ANT_FUNC_END();
+}
+
+ANTStatus ant_enable_radio(void)
+{
+   int iLockResult;
+   ANTStatus uiRet = 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_do_enable() < 0) {
+      ANT_ERROR("ant enable failed: %s", strerror(errno));
+
+      ant_do_disable();
+
+      if (g_fnStateCallback)
+         g_fnStateCallback(ant_radio_enabled_status());
+   } else {
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_ENABLED);
+      uiRet = 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 uiRet;
+}
+
+ANTStatus ant_disable_radio(void)
+{
+   int iLockResult;
+   ANTStatus uiRet = 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_do_disable();
+
+   if (g_fnStateCallback)
+      g_fnStateCallback(ant_radio_enabled_status());
+   uiRet = 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 uiRet;
+}
+
+ANTRadioEnabledStatus ant_radio_enabled_status(void)
+{
+   enum 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;
+}
+
+const char *ant_get_lib_version()
+{
+   return "libantradio.so: CHIP_B Character Device Transport. Version "
+      LIBANT_STACK_MAJOR"."LIBANT_STACK_MINOR"."LIBANT_STACK_INCRE;
+}
+
diff --git a/src/chip-B/ant_rx_chardev.c b/src/chip-B/ant_rx_chardev.c
new file mode 100644
index 0000000..c4aedac
--- /dev/null
+++ b/src/chip-B/ant_rx_chardev.c
@@ -0,0 +1,213 @@
+/*
+ * 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 provides the rx function which will loop reading ANT messages
+*        until told to exit.
+*
+*
+\*******************************************************************************/
+
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+
+#include "ant_rx_chardev.h"
+#include "ant_native_chardev.h"
+
+#include "ant_native.h"
+#include "ant_types.h"
+#include "ant_log.h"
+#undef LOG_TAG
+#define LOG_TAG "antradio_rx"
+
+#define ANT_POLL_TIMEOUT         ((int)30000)
+
+int readChannelMsg(ant_channel_info_t *pstChnlInfo)
+{
+   int iRet = -1;
+   ANT_U8 aucRxBuffer[ANT_HCI_MAX_MSG_SIZE];
+   int iRxLenRead;
+   int iMutexResult;
+   ANT_FUNC_START();
+
+   while (((iRxLenRead = read(pstChnlInfo->iFd, aucRxBuffer, sizeof(aucRxBuffer))) < 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, iRxLenRead, 'R');
+      if (aucRxBuffer[CHIP_B_HCI_DATA_OFFSET + ANT_MSG_ID_OFFSET] == ANT_MESG_FLOW_CONTROL) {
+         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));
+            goto out;
+         }
+         ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);
+
+         pstChnlInfo->ucFlowControlResp = aucRxBuffer[CHIP_B_HCI_DATA_OFFSET + ANT_MSG_DATA_OFFSET];
+
+         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);
+      } else {
+         if (pstChnlInfo->fnRxCallback != NULL) {
+            pstChnlInfo->fnRxCallback(aucRxBuffer[CHIP_B_HCI_SIZE_OFFSET], &aucRxBuffer[CHIP_B_HCI_DATA_OFFSET]);
+         } else {
+            ANT_WARN("%s rx callback is null", pstChnlInfo->pcDevicePath);
+         }
+      }
+      iRet = 0;
+   }
+out:
+   ANT_FUNC_END();
+   return iRet;
+}
+
+void *fnRxThread(void *ant_rx_thread_info)
+{
+   int iMutexLockResult;
+   int iPollRet;
+   ant_rx_thread_info_t *stRxThreadInfo;
+   struct pollfd astPollFd[NUM_ANT_CHANNELS];
+   enum 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;
+   }
+
+   while (stRxThreadInfo->ucRunThread) {
+      iPollRet = poll(astPollFd, NUM_ANT_CHANNELS, 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));
+      } 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",
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+               /* Chip was reset or other error, only way to recover is to
+                * close and open ANT chardev */
+               stRxThreadInfo->ucChipResetting = 1;
+               if (g_fnStateCallback)
+                  g_fnStateCallback(RADIO_STATUS_RESETTING);
+               goto reset;
+
+            } else if (astPollFd[eChannel].revents & (POLLIN | POLLRDNORM)) {
+               ANT_DEBUG_D("data on %s. reading it",
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+               if (readChannelMsg(&stRxThreadInfo->astChannels[eChannel]) < 0)
+                  goto out;
+            } else if (astPollFd[eChannel].revents) {
+               ANT_DEBUG_W("unhandled poll result %#x from %s",
+                            astPollFd[eChannel].revents,
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+            }
+         }
+      }
+   }
+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 */
+   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 */
+
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_DISABLING);
+
+      ant_do_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");
+   }
+   ANT_FUNC_END();
+#ifdef ANDROID
+   return NULL;
+#endif
+
+reset:
+   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_do_disable();
+
+      if (ant_do_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();
+#ifdef ANDROID
+   return NULL;
+#endif
+}
+
diff --git a/src/chip-B/inc/ant_native_chardev.h b/src/chip-B/inc/ant_native_chardev.h
new file mode 100644
index 0000000..1173f08
--- /dev/null
+++ b/src/chip-B/inc/ant_native_chardev.h
@@ -0,0 +1,48 @@
+/*
+ * 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.h
+*
+*   BRIEF:
+*       This file defines constants for the char dev implementation
+*
+*
+\*******************************************************************************/
+
+#ifndef __ANT_NATIVE_CHARDEV_H
+#define __ANT_NATIVE_CHARDEV_H
+
+#define ANT_COMMANDS_DEVICE_NAME             "/dev/antradio_cmd"
+#define ANT_DATA_DEVICE_NAME                 "/dev/antradio_data"
+
+#define CHIP_B_HCI_SIZE_OFFSET               0
+#define CHIP_B_HCI_DATA_OFFSET               1
+#define CHIP_B_HCI_HEADER_SIZE               1
+
+#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)
+#define FLOW_GO                              ((ANT_U8)0x00)
+#define FLOW_STOP                            ((ANT_U8)0x80)
+#define CHIP_B_FLOW_GO_WAIT_TIMEOUT_SEC      10
+
+int ant_do_enable(void);
+void ant_do_disable(void);
+extern ANTNativeANTStateCb g_fnStateCallback;
+
+#endif /* ifndef __ANT_NATIVE_CHARDEV_H */
+
diff --git a/src/chip-B/inc/ant_rx_chardev.h b/src/chip-B/inc/ant_rx_chardev.h
new file mode 100644
index 0000000..6721222
--- /dev/null
+++ b/src/chip-B/inc/ant_rx_chardev.h
@@ -0,0 +1,73 @@
+/*
+ * 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 public members in ant_rx_chardev.c
+*
+*
+\*******************************************************************************/
+
+#ifndef __ANT_RX_NATIVE_H
+#define __ANT_RX_NATIVE_H
+
+#include "ant_native.h"
+
+/* 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;
+} ant_channel_info_t;
+
+enum ant_channel_type {
+   DATA_CHANNEL,
+   COMMAND_CHANNEL,
+   NUM_ANT_CHANNELS
+};
+
+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;
+
+/* 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/chip-C/Android.mk b/src/chip-C/Android.mk
new file mode 100644
index 0000000..1f75535
--- /dev/null
+++ b/src/chip-C/Android.mk
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+ifeq ($(BOARD_ANT_WIRELESS_DEVICE),"chip-C")
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -g -c -W -Wall -O2
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/../common/inc \
+    $(LOCAL_PATH)/inc \
+
+LOCAL_SRC_FILES:= \
+    ../../JAntNative.cpp \
+    ../common/ant_utils.c \
+    ant_native_chardev.c \
+    ant_rx_chardev.c \
+
+#JNI
+LOCAL_C_INCLUDE += $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES += \
+    libnativehelper
+
+# logging
+LOCAL_SHARED_LIBRARIES += \
+    libcutils
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libantradio
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # BOARD_ANT_WIRELESS_DEVICE = "chip-C"
diff --git a/src/chip-C/ant_native_chardev.c b/src/chip-C/ant_native_chardev.c
new file mode 100644
index 0000000..fe10382
--- /dev/null
+++ b/src/chip-C/ant_native_chardev.c
@@ -0,0 +1,389 @@
+/*
+ * 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 character device implementation of ant_native.h
+*
+*
+\*******************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h> /* for open() */
+#include <linux/ioctl.h>
+#include <pthread.h>
+
+#include "ant_native.h"
+#include "ant_types.h"
+#include "ant_log.h"
+#include "ant_version.h"
+
+#include "ant_native_chardev.h"
+#include "ant_rx_chardev.h"
+
+#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)
+
+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 void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName)
+{
+   pstChnlInfo->pcDevicePath = pcCharDevName;
+   pstChnlInfo->iFd = -1;
+   pstChnlInfo->fnRxCallback = NULL;
+   pstChnlInfo->ucFlowControlResp = FLOW_GO;
+   pstChnlInfo->pstFlowControlCond = &stFlowControlCond;
+   pstChnlInfo->pstFlowControlLock = &stFlowControlLock;
+}
+
+ANTStatus ant_init(void)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+   stRxThreadInfo.stRxThread = 0;
+   stRxThreadInfo.ucRunThread = 0;
+   stRxThreadInfo.ucChipResetting = 0;
+   stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
+   g_fnStateCallback = 0;
+   ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
+   ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
+   uiRet = ANT_STATUS_SUCCESS;
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus ant_deinit(void)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   ANT_FUNC_START();
+   uiRet = ANT_STATUS_SUCCESS;
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
+{
+   ANT_FUNC_START();
+   stRxThreadInfo.astChannels[COMMAND_CHANNEL].fnRxCallback = rx_callback_func;
+   stRxThreadInfo.astChannels[DATA_CHANNEL].fnRxCallback = rx_callback_func;
+   ANT_FUNC_END();
+   return ANT_STATUS_SUCCESS;
+}
+
+ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func)
+{
+   ANT_FUNC_START();
+   g_fnStateCallback = state_callback_func;
+   ANT_FUNC_END();
+   return ANT_STATUS_SUCCESS;
+}
+
+ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg)
+{
+   ANTStatus uiRet = ANT_STATUS_FAILED;
+   int iMutexResult;
+   int iResult;
+   struct timespec stTimeout;
+   int iCondWaitResult;
+   ANT_U8 txBuffer[ANT_HCI_MAX_MSG_SIZE];
+   ANT_FUNC_START();
+   if (ant_radio_enabled_status() != RADIO_STATUS_ENABLED) {
+      uiRet = ANT_STATUS_FAILED_BT_NOT_INITIALIZED;
+      goto out;
+   }
+   txBuffer[CHIP_C_HCI_SIZE_OFFSET] = ucLen;
+   memcpy(txBuffer + CHIP_C_HCI_HEADER_SIZE, pucMesg, ucLen);
+   ANT_SERIAL(txBuffer, ucLen + CHIP_C_HCI_HEADER_SIZE, 'T');
+   switch (txBuffer[CHIP_C_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:
+      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[COMMAND_CHANNEL].ucFlowControlResp = FLOW_STOP;
+      iResult = write(stRxThreadInfo.astChannels[DATA_CHANNEL].iFd, txBuffer, ucLen + CHIP_C_HCI_HEADER_SIZE);
+      if (iResult < 0) {
+         ANT_ERROR("failed to write data message to device: %s", strerror(errno));
+      } else if (iResult != ucLen + CHIP_C_HCI_HEADER_SIZE) {
+         ANT_ERROR("bytes written and message size dont match up");
+      } else {
+         stTimeout.tv_sec = time(0) + CHIP_C_FLOW_GO_WAIT_TIMEOUT_SEC;
+         stTimeout.tv_nsec = 0;
+
+         while (stRxThreadInfo.astChannels[COMMAND_CHANNEL].ucFlowControlResp != 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)
+                  uiRet = ANT_STATUS_HARDWARE_ERR;
+               goto wait_error;
+            }
+         }
+         uiRet = 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__);
+      break;
+   default:
+      iResult = write(stRxThreadInfo.astChannels[COMMAND_CHANNEL].iFd, txBuffer, ucLen + CHIP_C_HCI_HEADER_SIZE);
+      if (iResult < 0) {
+         ANT_ERROR("failed to write message to device: %s", strerror(errno));
+      }  else if (iResult != ucLen + CHIP_C_HCI_HEADER_SIZE) {
+         ANT_ERROR("bytes written and message size dont match up");
+      } else {
+         uiRet = ANT_STATUS_SUCCESS;
+      }
+   }
+out:
+   ANT_FUNC_END();
+   return uiRet;
+}
+
+ANTStatus ant_radio_hard_reset(void)
+{
+   ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
+   ANT_FUNC_START();
+   ANT_FUNC_END();
+   return result_status;
+}
+
+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) {
+      if (close(pstChnlInfo->iFd) < 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) {
+      pstChnlInfo->iFd = open(pstChnlInfo->pcDevicePath, O_RDWR);
+      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;
+}
+
+int ant_do_enable(void)
+{
+   int iRet = -1;
+   enum ant_channel_type eChannel;
+   ANT_FUNC_START();
+
+   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;
+}
+
+void ant_do_disable(void)
+{
+   enum ant_channel_type eChannel;
+   ANT_FUNC_START();
+   stRxThreadInfo.ucRunThread = 0;
+   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++)
+      ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]);
+   if (stRxThreadInfo.stRxThread != 0) {
+      if (pthread_join(stRxThreadInfo.stRxThread, NULL) < 0) {
+         ANT_ERROR("failed to join rx thread: %s", strerror(errno));
+      }
+      stRxThreadInfo.stRxThread = 0;
+   } else {
+      ANT_DEBUG_D("rx thread is not running");
+   }
+   ANT_FUNC_END();
+}
+
+ANTStatus ant_enable_radio(void)
+{
+   int iLockResult;
+   ANTStatus uiRet = 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_do_enable() < 0) {
+      ANT_ERROR("ant enable failed: %s", strerror(errno));
+
+      ant_do_disable();
+
+      if (g_fnStateCallback)
+         g_fnStateCallback(ant_radio_enabled_status());
+   } else {
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_ENABLED);
+      uiRet = 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 uiRet;
+}
+
+ANTStatus ant_disable_radio(void)
+{
+   int iLockResult;
+   ANTStatus uiRet = 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_do_disable();
+
+   if (g_fnStateCallback)
+      g_fnStateCallback(ant_radio_enabled_status());
+   uiRet = 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 uiRet;
+}
+
+ANTRadioEnabledStatus ant_radio_enabled_status(void)
+{
+   enum 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;
+}
+
+const char *ant_get_lib_version()
+{
+   return "libantradio.so: CHIP_C TTY Transport. Version "
+      LIBANT_STACK_MAJOR"."LIBANT_STACK_MINOR"."LIBANT_STACK_INCRE;
+}
+
diff --git a/src/chip-C/ant_rx_chardev.c b/src/chip-C/ant_rx_chardev.c
new file mode 100644
index 0000000..2c0c6bd
--- /dev/null
+++ b/src/chip-C/ant_rx_chardev.c
@@ -0,0 +1,213 @@
+/*
+ * 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 provides the rx function which will loop reading ANT messages
+*        until told to exit.
+*
+*
+\*******************************************************************************/
+
+#include <errno.h>
+#include <poll.h>
+#include <pthread.h>
+
+#include "ant_rx_chardev.h"
+#include "ant_native_chardev.h"
+
+#include "ant_native.h"
+#include "ant_types.h"
+#include "ant_log.h"
+#undef LOG_TAG
+#define LOG_TAG "antradio_rx"
+
+#define ANT_POLL_TIMEOUT         ((int)30000)
+
+int readChannelMsg(ant_channel_info_t *pstChnlInfo)
+{
+   int iRet = -1;
+   ANT_U8 aucRxBuffer[ANT_HCI_MAX_MSG_SIZE];
+   int iRxLenRead;
+   int iMutexResult;
+   ANT_FUNC_START();
+
+   while (((iRxLenRead = read(pstChnlInfo->iFd, aucRxBuffer, sizeof(aucRxBuffer))) < 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, iRxLenRead, 'R');
+      if (aucRxBuffer[CHIP_C_HCI_DATA_OFFSET + ANT_MSG_ID_OFFSET] == ANT_MESG_FLOW_CONTROL) {
+         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));
+            goto out;
+         }
+         ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);
+
+         pstChnlInfo->ucFlowControlResp = aucRxBuffer[CHIP_C_HCI_DATA_OFFSET + ANT_MSG_DATA_OFFSET];
+
+         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);
+      } else {
+         if (pstChnlInfo->fnRxCallback != NULL) {
+            pstChnlInfo->fnRxCallback(aucRxBuffer[CHIP_C_HCI_SIZE_OFFSET], &aucRxBuffer[CHIP_C_HCI_DATA_OFFSET]);
+         } else {
+            ANT_WARN("%s rx callback is null", pstChnlInfo->pcDevicePath);
+         }
+      }
+      iRet = 0;
+   }
+out:
+   ANT_FUNC_END();
+   return iRet;
+}
+
+void *fnRxThread(void *ant_rx_thread_info)
+{
+   int iMutexLockResult;
+   int iPollRet;
+   ant_rx_thread_info_t *stRxThreadInfo;
+   struct pollfd astPollFd[NUM_ANT_CHANNELS];
+   enum 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;
+   }
+
+   while (stRxThreadInfo->ucRunThread) {
+      iPollRet = poll(astPollFd, NUM_ANT_CHANNELS, 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));
+      } 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",
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+               /* Chip was reset or other error, only way to recover is to
+                * close and open ANT chardev */
+               stRxThreadInfo->ucChipResetting = 1;
+               if (g_fnStateCallback)
+                  g_fnStateCallback(RADIO_STATUS_RESETTING);
+               goto reset;
+
+            } else if (astPollFd[eChannel].revents & (POLLIN | POLLRDNORM)) {
+               ANT_DEBUG_D("data on %s. reading it",
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+               if (readChannelMsg(&stRxThreadInfo->astChannels[eChannel]) < 0)
+                  goto out;
+            } else if (astPollFd[eChannel].revents) {
+               ANT_DEBUG_W("unhandled poll result %#x from %s",
+                            astPollFd[eChannel].revents,
+                            stRxThreadInfo->astChannels[eChannel].pcDevicePath);
+            }
+         }
+      }
+   }
+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 */
+   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 */
+
+      if (g_fnStateCallback)
+         g_fnStateCallback(RADIO_STATUS_DISABLING);
+
+      ant_do_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");
+   }
+   ANT_FUNC_END();
+#ifdef ANDROID
+   return NULL;
+#endif
+
+reset:
+   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_do_disable();
+
+      if (ant_do_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();
+#ifdef ANDROID
+   return NULL;
+#endif
+}
+
diff --git a/src/chip-C/inc/ant_native_chardev.h b/src/chip-C/inc/ant_native_chardev.h
new file mode 100644
index 0000000..c72ac0e
--- /dev/null
+++ b/src/chip-C/inc/ant_native_chardev.h
@@ -0,0 +1,48 @@
+/*
+ * 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.h
+*
+*   BRIEF:
+*       This file defines constants for the char dev implementation
+*
+*
+\*******************************************************************************/
+
+#ifndef __ANT_NATIVE_CHARDEV_H
+#define __ANT_NATIVE_CHARDEV_H
+
+#define ANT_COMMANDS_DEVICE_NAME             "/dev/smd5"
+#define ANT_DATA_DEVICE_NAME                 "/dev/smd6"
+
+#define CHIP_C_HCI_SIZE_OFFSET               0
+#define CHIP_C_HCI_DATA_OFFSET               1
+#define CHIP_C_HCI_HEADER_SIZE               1
+
+#define ANT_MESG_FLOW_CONTROL                ((ANT_U8)0xC9)
+#define FLOW_GO                              ((ANT_U8)0x00)
+#define FLOW_STOP                            ((ANT_U8)0x80)
+#define CHIP_C_FLOW_GO_WAIT_TIMEOUT_SEC      10
+
+int ant_do_enable(void);
+void ant_do_disable(void);
+extern ANTNativeANTStateCb g_fnStateCallback;
+
+#endif /* ifndef __ANT_NATIVE_CHARDEV_H */
+
diff --git a/src/chip-C/inc/ant_rx_chardev.h b/src/chip-C/inc/ant_rx_chardev.h
new file mode 100644
index 0000000..6721222
--- /dev/null
+++ b/src/chip-C/inc/ant_rx_chardev.h
@@ -0,0 +1,73 @@
+/*
+ * 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 public members in ant_rx_chardev.c
+*
+*
+\*******************************************************************************/
+
+#ifndef __ANT_RX_NATIVE_H
+#define __ANT_RX_NATIVE_H
+
+#include "ant_native.h"
+
+/* 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;
+} ant_channel_info_t;
+
+enum ant_channel_type {
+   DATA_CHANNEL,
+   COMMAND_CHANNEL,
+   NUM_ANT_CHANNELS
+};
+
+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;
+
+/* 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/common/ant_utils.c b/src/common/ant_utils.c
new file mode 100644
index 0000000..65b35de
--- /dev/null
+++ b/src/common/ant_utils.c
@@ -0,0 +1,57 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_utils.c
+*
+*   BRIEF:          
+*		This file contains utility functions
+*
+*
+\******************************************************************************/
+
+#include "ant_types.h"
+#include "ant_utils.h"
+
+
+ANT_U16 ANT_UTILS_BEtoHost16(ANT_U8 * num)
+{
+    return (ANT_U16)(((ANT_U16) *(num) << 8) | ((ANT_U16) *(num+1)));
+}
+ANT_U16 ANT_UTILS_LEtoHost16(ANT_U8 * num)
+{
+    return (ANT_U16)(((ANT_U16) *(num+1) << 8) | ((ANT_U16) *(num)));
+}
+void ANT_UTILS_StoreBE16(ANT_U8 *buff, ANT_U16 be_value) 
+{
+   buff[0] = (ANT_U8)(be_value>>8);
+   buff[1] = (ANT_U8)be_value;
+}
+void ANT_UTILS_StoreLE16(ANT_U8 *buff, ANT_U16 le_value) 
+{
+   buff[1] = (ANT_U8)(le_value>>8);
+   buff[0] = (ANT_U8)le_value;
+}
+
+void ANT_UTILS_StoreBE32(ANT_U8 *buff, ANT_U32 be_value) 
+{
+   buff[0] = (ANT_U8)(be_value>>24);
+   buff[1] = (ANT_U8)(be_value>>16);
+   buff[2] = (ANT_U8)(be_value>>8);
+   buff[3] = (ANT_U8)be_value;
+}
diff --git a/src/common/inc/ant_log.h b/src/common/inc/ant_log.h
new file mode 100644
index 0000000..f2d09b5
--- /dev/null
+++ b/src/common/inc/ant_log.h
@@ -0,0 +1,174 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_log.h
+*
+*   BRIEF:          
+*		This file defines logging functions
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_LOG_H
+#define __ANT_LOG_H
+
+#include <unistd.h>
+#include "ant_types.h"
+
+#define LEVEL_NONE      0
+#define LEVEL_ERROR     1
+#define LEVEL_WARNING   2
+#define LEVEL_INFO      3
+#define LEVEL_DEBUG     4
+#define LEVEL_VERBOSE   5
+
+#define STREAM_STDOUT   16
+#define STREAM_LOGCAT   17
+
+/* Define what stream output should go to depending on platform */
+#if defined(__ANDROID__) || defined(ANDROID)
+   #define ANT_OUTPUT_STREAM STREAM_LOGCAT
+#elif defined(__linux__) || defined(__linux) || defined(linux)
+   #define ANT_OUTPUT_STREAM STREAM_STDOUT
+#endif
+
+/* If no debug level defined, set default as none */
+#if !defined(ANT_DEBUG)
+   #define ANT_DEBUG LEVEL_NONE
+#endif
+
+/* Define to show function entry and exit */
+//#define ANT_STACK_TRACE
+
+/* Define to show message in byte form */
+//#define ANT_LOG_SERIAL
+
+/* Define to write serial log to file instead of logcat */
+//#define ANT_LOG_SERIAL_FILE "/data/system/antseriallog.txt"
+
+#undef LOG_TAG
+#define LOG_TAG "antradio"
+
+#if ANT_DEBUG == LEVEL_NONE
+   #undef ANT_STACK_TRACE
+   #undef ANT_LOG_SERIAL
+#endif
+
+#if ANT_DEBUG >= LEVEL_ERROR
+   #define OUTPUT_LEVEL_ERROR(...)     OUTPUT_ERROR(__VA_ARGS__)
+#else
+   #define OUTPUT_LEVEL_ERROR(...)     ((void)0)
+#endif
+#if ANT_DEBUG >= LEVEL_WARNING
+   #define OUTPUT_LEVEL_WARNING(...)   OUTPUT_WARNING(__VA_ARGS__)
+#else
+   #define OUTPUT_LEVEL_WARNING(...)   ((void)0)
+#endif
+#if ANT_DEBUG >= LEVEL_INFO
+   #define OUTPUT_LEVEL_INFO(...)      OUTPUT_INFO(__VA_ARGS__)
+#else
+   #define OUTPUT_LEVEL_INFO(...)      ((void)0)
+#endif
+#if ANT_DEBUG >= LEVEL_DEBUG
+   #define OUTPUT_LEVEL_DEBUG(...)     OUTPUT_DEBUG(__VA_ARGS__)
+#else
+   #define OUTPUT_LEVEL_DEBUG(...)     ((void)0)
+#endif
+#if ANT_DEBUG >= LEVEL_VERBOSE
+   #define OUTPUT_LEVEL_VERBOSE(...)   OUTPUT_VERBOSE(__VA_ARGS__)
+#else
+   #define OUTPUT_LEVEL_VERBOSE(...)   ((void)0)
+#endif
+
+#if ANT_OUTPUT_STREAM == STREAM_STDOUT
+   #include <stdio.h>
+   #define OUTPUT_VERBOSE(fmt, ...)    fprintf(stdout, LOG_TAG "<V>: " fmt "\n", ##__VA_ARGS__)
+   #define OUTPUT_DEBUG(fmt, ...)      fprintf(stdout, LOG_TAG "<D>: " fmt "\n", ##__VA_ARGS__)
+   #define OUTPUT_INFO(fmt, ...)       fprintf(stdout, LOG_TAG "<I>: " fmt "\n", ##__VA_ARGS__)
+   #define OUTPUT_WARNING(fmt, ...)    fprintf(stdout, LOG_TAG "<W>: " fmt "\n", ##__VA_ARGS__)
+   #define OUTPUT_ERROR(fmt, ...)      fprintf(stdout, LOG_TAG "<E>: " fmt "\n", ##__VA_ARGS__)
+#elif ANT_OUTPUT_STREAM == STREAM_LOGCAT
+   #if (ANT_DEBUG >= LEVEL_VERBOSE) || (defined(ANT_LOG_SERIAL) && !defined(ANT_LOG_SERIAL_FILE))
+      #undef NDEBUG /* Define verbose logging for logcat if required */
+   #endif
+   #include <cutils/log.h>
+   #define OUTPUT_VERBOSE(...)         LOGV(__VA_ARGS__)
+   #define OUTPUT_DEBUG(...)           LOGD(__VA_ARGS__)
+   #define OUTPUT_INFO(...)            LOGI(__VA_ARGS__)
+   #define OUTPUT_WARNING(...)         LOGW(__VA_ARGS__)
+   #define OUTPUT_ERROR(...)           LOGE(__VA_ARGS__)
+#endif
+
+#define ANT_WARN(...)                  OUTPUT_WARNING(__VA_ARGS__)
+#define ANT_ERROR(...)                 OUTPUT_ERROR(__VA_ARGS__)
+
+#define ANT_DEBUG_V(...)               OUTPUT_LEVEL_VERBOSE(__VA_ARGS__)
+#define ANT_DEBUG_D(...)               OUTPUT_LEVEL_DEBUG(__VA_ARGS__)
+#define ANT_DEBUG_I(...)               OUTPUT_LEVEL_INFO(__VA_ARGS__)
+#define ANT_DEBUG_W(...)               OUTPUT_LEVEL_WARNING(__VA_ARGS__)
+#define ANT_DEBUG_E(...)               OUTPUT_LEVEL_ERROR(__VA_ARGS__)
+
+#if defined(ANT_STACK_TRACE)
+   #define ANT_FUNC_START()            OUTPUT_DEBUG("->  FUNC start %s", __FUNCTION__)
+   #define ANT_FUNC_END()              OUTPUT_DEBUG("<-  FUNC end   %s", __FUNCTION__)
+#else
+   #define ANT_FUNC_START()            ((void)0)
+   #define ANT_FUNC_END()              ((void)0)
+#endif
+
+#if defined(ANT_LOG_SERIAL)
+static inline void ANT_SERIAL(ANT_U8 *buf, ANT_U8 len, char dir)
+{
+   static const char hexToChar[] = {'0','1','2','3','4','5','6','7',
+                                    '8','9','A','B','C','D','E','F'};
+   int i;
+   static char log[1024];
+   char *ptr = log;
+
+   *(ptr++) = dir;
+   *(ptr++) = 'x';
+   *(ptr++) = ' ';
+   for (i = 0; i < len; i++) {
+      *(ptr++) = '[';
+      *(ptr++) = hexToChar[(buf[i] & 0xF0) >> 4];
+      *(ptr++) = hexToChar[(buf[i] & 0x0F) >> 0];
+      *(ptr++) = ']';
+   }
+#if defined(ANT_LOG_SERIAL_FILE)
+   *(ptr++) = '\n';
+   FILE *fd = NULL;
+   fd = fopen(ANT_LOG_SERIAL_FILE, "a");
+   if (NULL == fd) {
+      LOGW("Could not open %s for serial output. %s", ANT_LOG_SERIAL_FILE, strerror(errno));
+   } else {
+      fwrite(log, 1, (ptr - log), fd);
+      if (fclose(fd)) {
+         LOGW("Could not close file for serial output. %s", strerror(errno));
+      }
+   }
+#else
+   *(ptr++) = '\0';
+   OUTPUT_VERBOSE("%s", log);
+#endif
+}
+#else
+   #define ANT_SERIAL(...)             ((void)0)
+#endif
+
+#endif /* __ANT_LOG_H */
diff --git a/src/common/inc/ant_native.h b/src/common/inc/ant_native.h
new file mode 100644
index 0000000..eedec50
--- /dev/null
+++ b/src/common/inc/ant_native.h
@@ -0,0 +1,142 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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.h
+*
+*   BRIEF:
+*		This file defines the interface to the ANT transport layer
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_NATIVE_H
+#define __ANT_NATIVE_H
+
+/*******************************************************************************
+ *
+ * Include files
+ *
+ ******************************************************************************/
+#include "ant_types.h"
+
+/*******************************************************************************
+ *
+ * Constants
+ *
+ ******************************************************************************/
+#define ANT_NATIVE_MAX_PARMS_LEN              255
+#define ANT_NATIVE_MESSAGE_OVERHEAD_SIZE      2
+#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)
+
+/*******************************************************************************
+ *
+ * Types
+ *
+ ******************************************************************************/
+typedef void (*ANTNativeANTEventCb)(ANT_U8 ucLen, ANT_U8* pucData);
+typedef void (*ANTNativeANTStateCb)(ANTRadioEnabledStatus uiNewState);
+
+/*******************************************************************************
+ *
+ * Data Structures
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ * Function declarations
+ *
+ ******************************************************************************/
+
+/*------------------------------------------------------------------------------
+ * ant_init()
+ *
+ * Called to initialize the ANT stack
+ */
+ANTStatus ant_init(void);
+
+/*------------------------------------------------------------------------------
+ * ant_deinit()
+ *
+ * Called to de-initialize the ANT stack
+ */
+ANTStatus ant_deinit(void);
+
+/*------------------------------------------------------------------------------
+ * ant_enable_radio()
+ *
+ * Power on the chip and set it to a state which can read / write to it
+ */
+ANTStatus ant_enable_radio(void);
+
+/*------------------------------------------------------------------------------
+ * ant_disable_radio()
+ *
+ * Kill power to the ANT chip and set state which doesnt allow read / write
+ */
+ANTStatus ant_disable_radio(void);
+
+/*------------------------------------------------------------------------------
+ * ant_radio_enabled_status()
+ *
+ * Gets if the chip/transport is disabled/disabling/enabling/enabled
+ */
+ANTRadioEnabledStatus ant_radio_enabled_status(void);
+
+/*------------------------------------------------------------------------------
+ * set_ant_rx_callback()
+ *
+ * Sets the callback function for receiving ANT messages
+ */
+ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func);
+
+/*------------------------------------------------------------------------------
+ * set_ant_state_callback()
+ *
+ * Sets the callback function for any ANT radio enabled status state changes
+ */
+ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func);
+
+/*------------------------------------------------------------------------------
+ * ant_tx_message()
+ *
+ * Sends an ANT message command to the chip.
+ */
+ANTStatus ant_tx_message(ANT_U8 ucLen, ANT_U8 *pucMesg);
+
+/*------------------------------------------------------------------------------
+ * ant_radio_hard_reset()
+ *
+ * If supported, forces the chip to do a power cycle reset
+ */
+ANTStatus ant_radio_hard_reset(void);
+
+/*------------------------------------------------------------------------------
+ * ant_get_lib_version()
+ *
+ * Gets the current version and transport type of libantradio.so
+ */
+const char *ant_get_lib_version(void);
+
+#endif /* ifndef __ANT_NATIVE_H */
+
diff --git a/src/common/inc/ant_types.h b/src/common/inc/ant_types.h
new file mode 100644
index 0000000..bc896b6
--- /dev/null
+++ b/src/common/inc/ant_types.h
@@ -0,0 +1,125 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_types.h
+*
+*   BRIEF:
+*		This file defines types used in the ANT stack
+*
+*
+\******************************************************************************/
+
+#ifndef __ANT_TYPES_H
+#define __ANT_TYPES_H
+
+#include <stdint.h>
+
+/* -------------------------------------------------------------
+ *                  8 Bits Types
+ */
+typedef uint8_t     ANT_U8;
+typedef int8_t      ANT_S8;
+
+/* -------------------------------------------------------------
+ *                  16 Bits Types
+ */
+typedef uint16_t    ANT_U16;
+typedef int8_t      ANT_S16;
+
+/* -------------------------------------------------------------
+ *                  32 Bits Types
+ */
+typedef uint32_t    ANT_U32;
+typedef int32_t     ANT_S32;
+
+
+/* -------------------------------------------------------------
+ *          Native Integer Types (# of bits irrelevant)
+ */
+typedef int          ANT_INT;
+typedef unsigned int ANT_UINT;
+
+
+/* --------------------------------------------------------------
+ *                  Boolean Definitions
+ */
+typedef ANT_INT     ANT_BOOL;
+
+#define ANT_TRUE    (1 == 1)
+#define ANT_FALSE   (1 == 0)
+
+/*
+*/
+#define ANT_NO_VALUE                                    ((ANT_U32)0xFFFFFFFFUL)
+
+
+/* -------------------------------------------------------------
+ *              ANTRadioEnabledStatus Type
+ */
+typedef ANT_UINT ANTRadioEnabledStatus;
+
+#define RADIO_STATUS_UNKNOWN                          ((ANTRadioEnabledStatus)0)
+#define RADIO_STATUS_ENABLING                         ((ANTRadioEnabledStatus)1)
+#define RADIO_STATUS_ENABLED                          ((ANTRadioEnabledStatus)2)
+#define RADIO_STATUS_DISABLING                        ((ANTRadioEnabledStatus)3)
+#define RADIO_STATUS_DISABLED                         ((ANTRadioEnabledStatus)4)
+#define RADIO_STATUS_NOT_SUPPORTED                    ((ANTRadioEnabledStatus)5)
+#define RADIO_STATUS_SERVICE_NOT_INSTALLED            ((ANTRadioEnabledStatus)6)
+#define RADIO_STATUS_SERVICE_NOT_CONNECTED            ((ANTRadioEnabledStatus)7)
+#define RADIO_STATUS_RESETTING                        ((ANTRadioEnabledStatus)8)
+#define RADIO_STATUS_RESET                            ((ANTRadioEnabledStatus)9)
+
+/*------------------------------------------------------------------------------
+ * ANTStatus Type
+ *
+ */
+typedef ANT_UINT ANTStatus;
+
+#define ANT_STATUS_SUCCESS                                  ((ANTStatus)0)
+#define ANT_STATUS_FAILED                                   ((ANTStatus)1)
+#define ANT_STATUS_PENDING                                  ((ANTStatus)2)
+#define ANT_STATUS_INVALID_PARM                             ((ANTStatus)3)
+#define ANT_STATUS_IN_PROGRESS                              ((ANTStatus)4)
+#define ANT_STATUS_NOT_APPLICABLE                           ((ANTStatus)5)
+#define ANT_STATUS_NOT_SUPPORTED                            ((ANTStatus)6)
+#define ANT_STATUS_INTERNAL_ERROR                           ((ANTStatus)7)
+#define ANT_STATUS_TRANSPORT_INIT_ERR                       ((ANTStatus)8)
+#define ANT_STATUS_HARDWARE_ERR                             ((ANTStatus)9)
+#define ANT_STATUS_NO_VALUE_AVAILABLE                       ((ANTStatus)10)
+#define ANT_STATUS_CONTEXT_DOESNT_EXIST                     ((ANTStatus)11)
+#define ANT_STATUS_CONTEXT_NOT_DESTROYED                    ((ANTStatus)12)
+#define ANT_STATUS_CONTEXT_NOT_ENABLED                      ((ANTStatus)13)
+#define ANT_STATUS_CONTEXT_NOT_DISABLED                     ((ANTStatus)14)
+#define ANT_STATUS_NOT_DE_INITIALIZED                       ((ANTStatus)15)
+#define ANT_STATUS_NOT_INITIALIZED                          ((ANTStatus)16)
+#define ANT_STATUS_TOO_MANY_PENDING_CMDS                    ((ANTStatus)17)
+#define ANT_STATUS_DISABLING_IN_PROGRESS                    ((ANTStatus)18)
+
+#define ANT_STATUS_COMMAND_WRITE_FAILED                     ((ANTStatus)20)
+#define ANT_STATUS_SCRIPT_EXEC_FAILED                       ((ANTStatus)21)
+
+#define ANT_STATUS_FAILED_BT_NOT_INITIALIZED                ((ANTStatus)23)
+#define ANT_STATUS_AUDIO_OPERATION_UNAVAILIBLE_RESOURCES    ((ANTStatus)24)
+
+#define ANT_STATUS_TRANSPORT_UNSPECIFIED_ERROR              ((ANTStatus)30)
+
+#define ANT_STATUS_NO_VALUE                                 ((ANTStatus)100)
+
+#endif  /* __ANT_TYPES_H */
+
diff --git a/src/common/inc/ant_utils.h b/src/common/inc/ant_utils.h
new file mode 100644
index 0000000..60abe8c
--- /dev/null
+++ b/src/common/inc/ant_utils.h
@@ -0,0 +1,139 @@
+/*
+ * ANT Stack
+ *
+ * Copyright 2009 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_utils.h
+*
+*   BRIEF:          
+*		This file defines utility functions
+*
+*
+\******************************************************************************/
+#ifndef __ANT_UTILS_H
+#define __ANT_UTILS_H
+
+#include "ant_types.h"
+
+/****************************************************************************
+ *
+ * Type Definitions
+ *
+ ****************************************************************************/
+
+
+
+/*------------------------------------------------------------------------------
+ * ANT_xxx()
+ *
+ * Brief:  
+ *      xxx
+ *
+ * Description:
+ *      xxx
+ *
+ * Type:
+ *      Syxxx/As
+ *
+ * Parameters:
+ *      xxx [in]    - 
+ *
+ * Returns:
+ *      xxx
+ */
+ANT_U16 ANT_UTILS_BEtoHost16(ANT_U8 * num);
+/*------------------------------------------------------------------------------
+ * ANT_xxx()
+ *
+ * Brief:  
+ *      xxx
+ *
+ * Description:
+ *      xxx
+ *
+ * Type:
+ *      Syxxx/As
+ *
+ * Parameters:
+ *      xxx [in]    - 
+ *
+ * Returns:
+ *      xxx
+ */
+ANT_U16 ANT_UTILS_LEtoHost16(ANT_U8 * num);
+/*------------------------------------------------------------------------------
+ * ANT_xxx()
+ *
+ * Brief:  
+ *      xxx
+ *
+ * Description:
+ *      xxx
+ *
+ * Type:
+ *      Syxxx/As
+ *
+ * Parameters:
+ *      xxx [in]    - 
+ *
+ * Returns:
+ *      xxx
+ */
+void ANT_UTILS_StoreBE16(ANT_U8 *buff, ANT_U16 be_value) ;
+/*------------------------------------------------------------------------------
+ * ANT_xxx()
+ *
+ * Brief:  
+ *      xxx
+ *
+ * Description:
+ *      xxx
+ *
+ * Type:
+ *      Syxxx/As
+ *
+ * Parameters:
+ *      xxx [in]    - 
+ *
+ * Returns:
+ *      xxx
+ */
+void ANT_UTILS_StoreLE16(ANT_U8 *buff, ANT_U16 le_value) ;
+/*------------------------------------------------------------------------------
+ * ANT_xxx()
+ *
+ * Brief:  
+ *      xxx
+ *
+ * Description:
+ *      xxx
+ *
+ * Type:
+ *      Syxxx/As
+ *
+ * Parameters:
+ *      xxx [in]    - 
+ *
+ * Returns:
+ *      xxx
+ */
+void ANT_UTILS_StoreBE32(ANT_U8 *buff, ANT_U32 be_value) ;
+
+
+
+#endif  /* __ANT_UTILS_H */
+
diff --git a/src/common/inc/ant_version.h b/src/common/inc/ant_version.h
new file mode 100644
index 0000000..bc1f239
--- /dev/null
+++ b/src/common/inc/ant_version.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#ifndef __ANT_VERSION_H
+#define __ANT_VERSION_H
+
+#define LIBANT_STACK_MAJOR "0"
+#define LIBANT_STACK_MINOR "7"
+#define LIBANT_STACK_INCRE "0"
+
+#endif // __ANT_VERSION_H
+