Broke Android_System_package in to individual repositories
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 */
+